Skip to content

v0.7.0

Choose a tag to compare

@marcelsud marcelsud released this 26 Jul 11:44
· 37 commits to main since this release
9e8012e

⚠️ Breaking changes

  • createHttpInput returns an Effect. Its signature changed from Input<HttpInputError> to
    Effect<Input<HttpInputError>, HttpInputError> (#122). It is re-exported from the package root, so
    programmatic callers must run the Effect. The factory no longer hands back a ready input, because
    it does not resolve until the server has actually bound — that is the point of the fix.

    - const input = createHttpInput({ port: 8080 })
    + const input = yield* createHttpInput({ port: 8080 })
  • HTTP input bodies are bounded by default. max_body_bytes now defaults to 1048576 (1 MiB);
    it was previously unbounded (#117). Deployments accepting larger webhook bodies must set it
    explicitly, or those requests receive 413 Payload Too Large and the connection closes.

    input:
      http:
        port: 8080
        max_body_bytes: 10485760  # raise if you accept bodies above 1 MiB

Security

  • CVE-2026-52746 / GHSA-86vw-mfpg-wwv9 — jsonata 2.1.0 → 2.2.2 (#121). Versions below 2.2.0
    backtrack superlinearly in $toMillis ISO-8601 validation, and Cascade evaluates configured
    JSONata expressions against externally sourced message content. A crafted 48 KiB timestamp took
    741 ms on 2.1.0 and is sub-millisecond on 2.2.2. Reachable from mapping, filter, switch, HTTP, and
    testing expression paths.
  • Unbounded request buffering — HTTP input appended every chunk to memory with only a time
    limit, so one remote client could make allocation proportional to an arbitrary body (#117). Both
    declared Content-Length and streamed/chunked bodies are now rejected before the limit is
    exceeded.

Correctness and delivery

  • File input no longer reports success after a failed read (#119). A one-shot open/stat/read
    failure was logged but converted into normal completion, so a pipeline could not tell an unread
    source from an empty file. Accepted records now drain in order, then the stream fails with
    FileInputError.
  • HTTP input bind failures are typed (#122). An occupied or forbidden port emitted an unhandled
    event that crashed the process after falsely logging readiness. It now fails through
    HttpInputError / BuildError with host, port, and reason, releases the server on failure and
    interruption, and logs readiness only after a confirmed bind.
  • Branch processor preserves value types (#120). Content was copied via JSON.parse(JSON.stringify(...)),
    which turned undefined, bigint, and circular graphs into unrecoverable defects and silently
    coerced Date to a string. It now uses structuredClone, and genuinely uncloneable values fail as
    a typed BranchProcessorError that DLQ handling can route.

Also in this release

Pipeline output-permit deadlocks (#107), diagnostic retention bounds (#108), file-input restat before
chunk reads (#109), assert construction failure containment (#110), bounded file-input disk reads
(#102), pipeline-wide max_concurrent_outputs enforcement (#100), typed stdin stream failures (#98),
documented SQS message attributes (#96), atomic dedupe admission (#90), and the Dox AGENTS tree
(#111).

Verification

lint, build, and knip clean · 926 unit tests · 19 test:e2e · 14/14 e2e:all ·
dist/cascade --version → cascade v0.7.0

Full Changelog: v0.6.1...v0.7.0