heygen-com/hyperframes · error · Error
[handler] event has no recognised Action; unwrapped ${MAX_EN
Error message
[handler] event has no recognised Action; unwrapped ${MAX_ENVELOPE_DEPTH} levels of Payload/Input without finding one. What it means
Thrown by `unwrapEvent` after walking up to `MAX_ENVELOPE_DEPTH` (4) levels of Step Functions `Payload`/`Input` envelopes without finding an event whose `Action` is a known `LambdaAction`. The depth cap prevents infinite loops on malformed cyclic input while still tolerating unusual Map/Wait nesting.
Source
Thrown at packages/aws-lambda/src/handler.ts:195
let cursor: LambdaEvent = event;
for (let i = 0; i < MAX_ENVELOPE_DEPTH; i++) {
if (cursor && typeof cursor === "object") {
const obj = cursor as Record<string, unknown>;
if (typeof obj.Action === "string" && isLambdaAction(obj.Action)) {
return cursor as PlanEvent | RenderChunkEvent | AssembleEvent;
}
if ("Payload" in obj) {
cursor = obj.Payload as LambdaEvent;
continue;
}
if ("Input" in obj) {
cursor = obj.Input as LambdaEvent;
continue;
}
}
break;
}
throw new Error(
`[handler] event has no recognised Action; unwrapped ${MAX_ENVELOPE_DEPTH} levels of Payload/Input without finding one.`,
);
}
function isLambdaAction(value: string): value is LambdaAction {
return value === "plan" || value === "renderChunk" || value === "assemble";
}
/**
* Emit a single JSON line to stdout. CloudWatch ingests each line as a
* structured event; Logs Insights queries can `filter event="..."` and
* project specific fields. We write to stdout (not stderr) because
* Lambda's default destination for both is the same log group, and
* Logs Insights' INFO/ERROR level parser keys off the JSON `level`
* field, not the stream.
*/
function logEvent(payload: Record<string, unknown>): void {
console.log(JSON.stringify(payload));View on GitHub (pinned to c2996c8626)
Solutions
- Inspect the raw Lambda input in CloudWatch to confirm where the `Action` field actually sits.
- Fix the Step Functions state definition so the Lambda task input contains `{Action: ..., ...}` within 4 envelope levels.
- If a legitimate envelope exceeds depth 4, reconsider the state machine structure rather than bumping the cap.
- Verify the producer/orchestrator is emitting the discriminated event, not a wrapper or error object.
Example fix
// before: extra envelope layer pushes Action past depth 4
{ Payload: { Input: { Payload: { Input: { Payload: { Input: { Action: "plan" } } } } } } }
// after: flatten the state machine so Action lands within 4 levels
{ Payload: { Input: { Action: "plan" } } } Defensive patterns
Strategy: validation
Validate before calling
function findAction(event: unknown, maxDepth = 4): string | null {
let cursor: unknown = event;
for (let i = 0; i < maxDepth && cursor && typeof cursor === "object"; i++) {
const obj = cursor as Record<string, unknown>;
if (typeof obj.Action === "string" && /^(plan|renderChunk|assemble)$/.test(obj.Action)) {
return obj.Action;
}
cursor = obj.Payload ?? obj.Input;
}
return null;
}
// assert non-null before invoking the handler Try / catch
try {
unwrapEvent(event);
} catch (err) {
if (err instanceof Error && /no recognised Action/.test(err.message)) {
// log the raw event for diagnosis, surface a typed error to Step Functions
}
throw err;
} Prevention
- Define Step Functions task inputs so `{Action: ...}` sits within 2 envelope levels (Payload/Input).
- Unit-test unwrapEvent against the exact envelope shapes your state machine emits.
- Reject misrouted/error payloads at a validation Step before they reach the Lambda.
When it happens
Trigger: An event object whose nested `Payload`/`Input` chain (up to 4 deep) contains no field `Action` with value `plan`/`renderChunk`/`assemble` — e.g. a Step Functions error payload, a misrouted invocation, or an envelope deeper than 4 levels.
Common situations: Step Functions map-state iteration passing the raw item instead of `{Action: ...}`; a Catch/Retry path forwarding an error object to the Lambda; refactor that changed the envelope shape past depth 4; CDK/SAM template wiring the wrong input.
Related errors
- [handler] unknown Action: ${JSON.stringify((_exhaustive as {
- [handler] chunk URI at index ${i} is empty
- BeginFrame probe timeout before ${label}
- [chromium] Chrome binary unavailable (source=${source}): @sp
- [chromium] Chrome binary unavailable (source=${source}): HYP
AI-assisted analysis of heygen-com/hyperframes@c2996c8626 (2026-08-12).
Data as JSON: /api/errors/56794b5ccf5544f3.
Report an issue: GitHub.