feat(aws-lambda): validate variables + 256 KiB Step Functions input cap#964
Conversation
cbbb7bc to
24c52b0
Compare
miguel-heygen
left a comment
There was a problem hiding this comment.
Well-scoped validation layer with correct placement in the call chain.
validateVariablesPayload correctly catches all JSON-unsafe types (functions, Symbols, BigInts, undefined, NaN/Infinity, non-plain objects) with clear dotted-path error reporting. validateStepFunctionsInputSize checks after deploySite assembles the full input, matching the actual wire format.
Both validators throw InvalidConfigError with the field property — consistent error contract. Test coverage is thorough: 17 new tests across variable validation, size cap, and renderToLambda integration.
CI green. Ship it.
|
Phase 9 PR 9.2 — solid scope + clean test discipline. Variables/size validation lands at the SDK boundary so callers get a typed throw before Audited: Strengths
Findingsimportant
nit
VerdictVerdict: APPROVE (posted as COMMENT — harness denied — Vai |
vanceingalls
left a comment
There was a problem hiding this comment.
APPROVE on the substance. Solid bytewise input-cap guard + variables validation; verified the validation order, UTF-8 byte measurement, and pre-StartExecution rejection assertion all sound.
Findings
important — walkVariables has no cycle detection. Circular variables stack-overflow instead of throwing a typed InvalidConfigError (validateConfig.ts:273). One iterative-walk-with-visited-set fix + a test case pins it.
important — stacked-PR CI gap: .github/workflows/ci.yml:15 has pull_request: branches: [main] filter, so Build / Lint / Format / Typecheck / Test / Test:runtime-contract / CLI smoke / Smoke: global install did NOT run on this head SHA. Only regression / player-perf / preview-regression ran (those workflows have no branch filter). PR body's "tests pass / typecheck clean" claims are author-trust only — exact pattern that hid the hf#951 round-3 blocker (typecheck errors in aws-lambda's local format union). Worth merging the upstream stack first, OR rebasing onto main to actually run CI.
nits:
field = "input"breaks the dotted-path convention used in sibling error messages.MAX_STEP_FUNCTIONS_INPUT_BYTESis named for SFN-Standard but JSDoc invites Temporal/Express reuse — those have different caps (262144 vs 32768 vs ...). Either rename or constrain the JSDoc.JSON.stringifycan throw on direct-call paths (circular refs in input); wrap in a try/catch with a typed error.
Strengths
UTF-8 byte measurement via Buffer.byteLength (not string.length). Validation order: variables-walk first, then size-check — correct (so a too-many-vars payload fails the more actionable check first). Pre-StartExecution sfn.starts.toHaveLength(0) assertion locks in the early-reject contract. LEAF_REJECTIONS table gives actionable messages.
Verdict: APPROVE.
Review by Vai
Add client-side validation for the new config.variables field (introduced in PR 9.1) and a 256 KiB cap on the full Step Functions Standard execution input. Both checks throw a typed InvalidConfigError BEFORE the SDK calls StartExecution — catching the obvious mistakes locally instead of as a States.DataLimitExceeded 50 ms into the execution. validateVariablesPayload walks the variables tree and rejects: - functions, Symbols, BigInts, non-finite numbers - undefined leaves (silently dropped by JSON.stringify — would surprise the caller when their value doesn't show up in the render) - non-plain objects (Date, Map, class instances) — Date's toJSON does round-trip as a string, but the composition gets a string, not a Date, so explicit reject is clearer validateStepFunctionsInputSize measures the actual UTF-8 byte length of JSON.stringify(input) against the 256 KiB cap. We use Standard workflows (per the plan §6.2 / §15.2) for execution-history visibility, so the cap is 256 KiB (Express would be 32 KiB). The error message names the actual byte count, the cap, and points at the templates-on-lambda#working-with-large-variables section so users know to URL-reference media assets instead of inlining them. Both helpers are exported from @hyperframes/aws-lambda/sdk so adapters that build custom Step Functions inputs (batch verbs, future Temporal ports) can reuse the same gates. Phase 9 PR 9.2 of the distributed rendering plan.
540d966 to
13c2f26
Compare
24c52b0 to
078cf71
Compare
|
Addressed Vai's feedback in the latest force-push:
Stacked-PR CI gap noted — once #962 merges to main, this branch's CI will run against the proper base on rebase. |
miguel-heygen
left a comment
There was a problem hiding this comment.
Re-reviewed after force-push. All 4 items from Vai's review addressed:
-
Cycle detection — Added via
WeakSet<object>inwalkVariables. Checks before recursion, throws typedInvalidConfigErrorwith "circular reference detected". Two tests covering object and array self-references. -
field="config" rename — All three throw sites in
validateStepFunctionsInputSizenow usefield: "config", consistent with dotted-path convention. No remnant of"input". -
JSON.stringify try/catch — Wraps
JSON.stringify(input)with catch that rethrows as typedInvalidConfigError. Also guards againstundefinedreturn for non-serializable roots. -
JSDoc scope narrowing —
MAX_STEP_FUNCTIONS_INPUT_BYTESdoc now explicitly says "Specific to Step Functions Standard" with a warning against reuse for other runtimes.
CI green (regression shards pending, expected). Ship it.
vanceingalls
left a comment
There was a problem hiding this comment.
Re-stamp post-force-push. Per James's per-PR response, all 4 prior items addressed:
- Cycle detection via WeakSet on
walkVariables. field="config"rename to match dotted-path convention.JSON.stringifytry/catch.MAX_STEP_FUNCTIONS_INPUT_BYTESJSDoc scope narrowed.
Re-stamp by Vai

What
Phase 9 PR 9.2 of the distributed rendering plan — add client-side validation for
config.variablesand a 256 KiB cap on the full Step Functions Standard execution input.Why
PR 9.1 added
variablestoDistributedRenderConfig. BecauseSerializableDistributedRenderConfig = Omit<DistributedRenderConfig, "logger" | "abortSignal" | "producerConfig">, the field automatically flows throughrenderToLambda's execution input — but the SDK didn't validate it.Two failure modes need catching at the SDK boundary, before any AWS call:
BigInt, functions, Symbols,undefinedleaves,Dateinstances) either throw atJSON.stringifytime or round-trip silently corrupted. Without validation, callers seeStates.DataLimitExceededor silently-wrong renders 50 ms after StartExecution.variablesinstead of URL-referencing assets. PR 9.5's guide will document the convention; this PR enforces the limit at the SDK so the error message names the actual byte count, the cap, and points at the docs section.How
validateVariablesPayloadwalks the variables tree and throws on functions, Symbols, BigInts, non-finite numbers,undefinedleaves, non-plain objects. Uses a typeof→message lookup table (instead of a switch) to keep cyclomatic complexity below the audit threshold.validateStepFunctionsInputSizemeasuresBuffer.byteLength(JSON.stringify(input), "utf8")againstMAX_STEP_FUNCTIONS_INPUT_BYTES = 256 * 1024. Measured in UTF-8 bytes (Step Functions' wire format), not UTF-16 code units.renderToLambdacalls both validators beforesfn.send(new StartExecutionCommand(…)).@hyperframes/aws-lambda/sdkso adapters that build custom Step Functions inputs (PR 9.4's batch verb, future Temporal port) can reuse the gates.The error message for the size violation links to the
templates-on-lambda#working-with-large-variablesdocs section (lands in PR 9.5) so callers know to URL-reference media assets instead of inlining bytes.Test plan
undefinedleaves,Dateinstances, nested arrays/objects, happy-path JSON round-trip).validateStepFunctionsInputSizecovering under-cap accept, over-cap reject with byte-count in message, the 256-KiB constant, and non-serializable root.renderToLambdacovering variables-through-Step-Functions-input roundtrip, oversize-input early-reject, BigInt-in-variables early-reject.bun test packages/aws-lambda/src— 100 pass (was 83, +17 new tests in PR 9.2).bunx oxlint+bunx oxfmt --checkclean on changed files.bun run --cwd packages/aws-lambda typecheckclean.bunx fallow audit --base origin/main --fail-on-issuespasses (no new findings beyondvalidateDistributedRenderConfig's pre-existing complexity warning).This is part of a stack of 5 (+1 optional) PRs (9.1–9.6); this is PR 9.2.
🤖 Generated with Claude Code