heygen-com/hyperframes · error

[renderToLambda] stateMachineArn is required

Error message

[renderToLambda] stateMachineArn is required

What it means

Thrown by renderToLambda when opts.stateMachineArn is empty/falsy. The state machine ARN (from the SAM/CDK stack output RenderStateMachineArn) is the target of StartExecution; without it the Step Functions call would fail with a malformed-ARN error. The check is the second of three required-field guards (after bucketName, before the siteHandle/projectDir check).

Source

Thrown at packages/aws-lambda/src/sdk/renderToLambda.ts:89

  renderId: string;
  /** Full execution ARN; pass to {@link getRenderProgress}. */
  executionArn: string;
  bucketName: string;
  stateMachineArn: string;
  outputS3Uri: string;
  projectS3Uri: string;
  startedAt: string;
}

// fallow-ignore-next-line complexity
export async function renderToLambda(opts: RenderToLambdaOptions): Promise<RenderHandle> {
  validateDistributedRenderConfig(opts.config);

  if (!opts.bucketName) {
    throw new Error("[renderToLambda] bucketName is required");
  }
  if (!opts.stateMachineArn) {
    throw new Error("[renderToLambda] stateMachineArn is required");
  }
  if (!opts.siteHandle && !opts.projectDir) {
    throw new Error("[renderToLambda] either siteHandle or projectDir must be supplied");
  }

  const executionName = opts.executionName ?? `hf-render-${randomUUID()}`;
  const ext = formatExtension(opts.config.format);
  const outputKey = opts.outputKey ?? `renders/${executionName}/output${ext}`;
  const planOutputS3Prefix = formatS3Uri({
    bucket: opts.bucketName,
    key: `renders/${executionName}/`,
  });
  const outputS3Uri = formatS3Uri({ bucket: opts.bucketName, key: outputKey });

  const site =
    opts.siteHandle ??
    (await deploySite({
      projectDir: opts.projectDir as string,

View on GitHub (pinned to c2996c8626)

Solutions

  1. Read RenderStateMachineArn from the deployed stack outputs and pass it verbatim.
  2. Verify the ARN contains ':stateMachine:' (not ':execution:') — execution ARNs belong to a specific run.
  3. Assert non-empty before the call.
  4. If constructing the ARN manually, confirm region + account + machine name are correct.

Example fix

// before
await renderToLambda({ config, bucketName, stateMachineArn: process.env.HF_EXEC_ARN });
// wrong env var -> empty

// after
await renderToLambda({ config, bucketName, stateMachineArn: process.env.HF_STATE_MACHINE_ARN });
Defensive patterns

Strategy: validation

Validate before calling

function assertStateMachineArn(value: string | undefined): asserts value is string {
  if (!value) throw new Error('stateMachineArn is required');
  if (!value.includes(':stateMachine:')) throw new Error('expected a stateMachine ARN, got: ' + value);
}

Type guard

const isStateMachineArn = (v: unknown): v is string =>
  typeof v === 'string' && v.startsWith('arn:aws:states:') && v.includes(':stateMachine:');

Prevention

When it happens

Trigger: Stack output not read or mis-named; env var unset; the field is undefined because the caller built the options object conditionally and the ARN branch wasn't taken.

Common situations: SAM stack outputs read into a map keyed by a name that changed across versions; CDK construct renamed the output; passing executionArn (per-execution) instead of stateMachineArn (per-stack).

Related errors


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