heygen-com/hyperframes · error

[getRenderProgress] executionArn is required

Error message

[getRenderProgress] executionArn is required

What it means

Thrown by getRenderProgress when opts.executionArn is falsy. executionArn is the full Step Functions execution ARN returned by renderToLambda's RenderHandle; it is required for both DescribeExecution and the execution-history pagination. Without it the SDK call would fail with a generic validation error, so this surfaces the missing-field cause directly.

Source

Thrown at packages/aws-lambda/src/sdk/getRenderProgress.ts:93

  totalFrames: number | null;
  /** Total Lambda invocations scheduled so far (both optimized + raw task integrations). */
  lambdasInvoked: number;
  costs: RenderCost;
  /** Final output object if Assemble succeeded; `null` otherwise. */
  outputFile: { s3Uri: string; bytes: number | null } | null;
  errors: RenderError[];
  /** `true` once the execution has terminated in a non-`SUCCEEDED` state. */
  fatalErrorEncountered: boolean;
  startedAt: string;
  endedAt: string | null;
}

const DEFAULT_MEMORY_MB = 10240;

/** Pull a current progress snapshot for one render. */
export async function getRenderProgress(opts: GetRenderProgressOptions): Promise<RenderProgress> {
  if (!opts.executionArn) {
    throw new Error("[getRenderProgress] executionArn is required");
  }
  const sfn = opts.sfn ?? new SFNClient({ region: opts.region });
  const memoryMb = opts.defaultMemorySizeMb ?? DEFAULT_MEMORY_MB;

  const describe = await sfn.send(
    new DescribeExecutionCommand({ executionArn: opts.executionArn }),
  );
  const status = (describe.status ?? "RUNNING") as RenderStatus;
  const startedAt = describe.startDate?.toISOString() ?? new Date(0).toISOString();
  const endedAt = describe.stopDate?.toISOString() ?? null;

  const history = await loadFullHistory(sfn, opts.executionArn);
  const summary = summarizeHistory(history, memoryMb);

  const costs = computeRenderCost(summary.lambdaInvocations, summary.stateTransitions);
  const overallProgress = computeOverallProgress({
    status,
    totalFrames: summary.totalFrames,

View on GitHub (pinned to c2996c8626)

Solutions

  1. Thread the full executionArn from renderToLambda's RenderHandle into getRenderProgress.
  2. If you only have renderId + stateMachineArn, reconstruct the ARN: `${stateMachineArn.replace(':stateMachine:', ':execution:')}:${renderId}`.

Example fix

// before
const progress = await getRenderProgress({ executionArn: handle.renderId, region });

// after
const progress = await getRenderProgress({ executionArn: handle.executionArn, region });
Defensive patterns

Strategy: validation

Validate before calling

function assertExecutionArn(value: string | undefined): asserts value is string {
  if (!value || !value.includes(':execution:')) {
    throw new Error('executionArn must be a full Step Functions execution ARN');
  }
}

Type guard

const isExecutionArn = (v: unknown): v is string =>
  typeof v === 'string' && v.startsWith('arn:') && v.includes(':execution:');

Prevention

When it happens

Trigger: Calling getRenderProgress without threading executionArn from the RenderHandle returned by renderToLambda; passing a renderId (the short name) instead of the full execution ARN; passing undefined when the render hasn't started yet.

Common situations: Confusing renderId (hf-render-<uuid>) with executionArn (arn:aws:states:…:execution:<smArn>:<name>); storing only the render name in a queue and losing the ARN; polling before renderToLambda resolved.

Related errors


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