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

  1. Inspect the raw Lambda input in CloudWatch to confirm where the `Action` field actually sits.
  2. Fix the Step Functions state definition so the Lambda task input contains `{Action: ..., ...}` within 4 envelope levels.
  3. If a legitimate envelope exceeds depth 4, reconsider the state machine structure rather than bumping the cap.
  4. 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

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


AI-assisted analysis of heygen-com/hyperframes@c2996c8626 (2026-08-12). Data as JSON: /api/errors/56794b5ccf5544f3. Report an issue: GitHub.