Daily high, low, precipitation, snow, records and normals parsed from the official NWS Daily Climate Report (CLI) text for MIA, NYC, ORD and 18 more locations. Latest, date-range with NCEI history, or live running max/min from METARs.
Unreleased: every invalid input is a free row (1104g, local, not built or pushed; based on cloud build 0.1.6)
Change: every input rejected by parse_input (for example "abc" for a whole number, an unknown mode, a bad or placeholder contactEmail, a bad location code) used to fail the run through Actor.fail (exit 1, FAILED). It now ends like the 1104f wrong-type path: exit 0, one free status row (statusRow: true, status: error, charged: false), no RUN_SUMMARY, nothing fetched or charged, and the row's message is also the terminal status message: Invalid input, nothing was fetched or charged: <reason>. Each <reason> is the same text as before.
Unchanged: upstream, network and runtime failures (including the run failing when no location could be read); valid input; pricing and input schema.
Tests: tests/test_invalid_input.py gains an end-to-end test that runs the Actor offline on former exit-1 inputs and checks exit 0, one free row, the message and no RUN_SUMMARY.
Unreleased: invalid input no longer crashes (2026-11-04, local, not built or pushed; based on cloud build 0.1.5)
Fix: input that is not a JSON object (a string, number, null or list) crashed the run with exit 91. It now ends with exit 0 and one free status row (statusRow: true, charged: false, no RUN_SUMMARY): Invalid input, nothing was fetched or charged: the input must be a JSON object, got <type>.
Fix: an infinite number in a whole-number field (e.g. maxItems: Infinity) crashed with OverflowError and exit 91 before anything was fetched. It now ends the same way, reason a number field has the wrong type (Expected a whole number, got inf.).
Unchanged: every other invalid input (bad e-mail, unknown location, "abc" for a number, etc.) still fails the run through Actor.fail (exit 1) with the same message. The deliberate free sample rows (no contactEmail) and the free unparsed-report rows are unchanged.
Memory: defaultMemoryMbytes and defaultRunOptions.memoryMbytes are now 256 (were 1024), minMemoryMbytes 128 (was 256); max 2048 unchanged. The README names no memory size and already says there is no start fee.
Unreleased: example input - 2026-10-31 (actor.json version unchanged: 0.1; no code, input or pricing change)
.actor/actor.json: new exampleRunInput, equal to the input-schema prefill
({"mode": "latest", "cliLocations": ["MIA", "NYC", "ORD"], "reportKinds": ["full_day", "partial_day"], "maxItems": 100}).
It has no contactEmail, so like {} it runs the free sample path: no requests, 4 sample records
(isSample: true), nothing charged. {} behaviour and cost are unchanged.
tests/test_sample_mode.py: the no-e-mail test also runs the exampleRunInput, and a new test checks that it equals
the prefill, has no contactEmail, and gives the same records as {} with 0 requests and 0 charged.