Skip to content

fix(aws-lambda): resolve Chromium for handlePlan before invoking probe#1056

Merged
miguel-heygen merged 1 commit into
heygen-com:mainfrom
kiyeonjeon21:fix/aws-lambda-handle-plan-chromium-init
May 24, 2026
Merged

fix(aws-lambda): resolve Chromium for handlePlan before invoking probe#1056
miguel-heygen merged 1 commit into
heygen-com:mainfrom
kiyeonjeon21:fix/aws-lambda-handle-plan-chromium-init

Conversation

@kiyeonjeon21
Copy link
Copy Markdown
Contributor

@kiyeonjeon21 kiyeonjeon21 commented May 24, 2026

What

Mirror the PRODUCER_HEADLESS_SHELL_PATH guard from handleRenderChunk inside handlePlan so the producer's probe stage can launch Chromium on a cold container.

Fixes #1055.

Why

Plan invocations crash the moment runProbeStage calls puppeteer.launch on a cold Lambda container. The producer relies on PRODUCER_HEADLESS_SHELL_PATH to find the bundled Sparticuz binary, but only handleRenderChunk was setting it. When the Plan stage needs a browser probe (root duration unknown, unresolved nested compositions, or data-hf-auto-start media), plan never resolves Chrome, and puppeteer-core throws An executablePath or channel must be specified for puppeteer-core.

Inline requestAnimationFrame(...) is related but separate: it routes capture through screenshot mode later in the pipeline, but it does not by itself force the Plan-stage browser probe unless one of the probe conditions above is also present.

A warm Lambda execution environment that previously served a render-chunk can happen to work because the env var is sticky. Within a single Step Functions execution, Plan still runs before RenderChunks, so cold Plan invocations need the same guard.

handleAssemble doesn't launch Chromium so it doesn't need the guard.

How

  • handlePlan gains the same four-line block handleRenderChunk already has — skipChromeResolution short-circuit, then resolveChromeExecutablePath() followed by process.env.PRODUCER_HEADLESS_SHELL_PATH = chromePath.
  • New dispatch test pre-seeds PRODUCER_HEADLESS_SHELL_PATH with a sentinel, runs plan without skipChromeResolution, and asserts the env var is preserved (i.e. the guard short-circuited instead of overwriting).

Test plan

  • bun --filter @hyperframes/aws-lambda test — 110 pass / 0 fail (109 prior + 1 new).
  • bun --filter @hyperframes/aws-lambda typecheck clean.
  • bun run lint clean.
  • bun run format:check clean.
  • Manual: ran a project against a hyperframes lambda deploy'd stack — plan now writes plan.tar.gz and chunks proceed instead of failing at the puppeteer assertion.

Notes

I considered hoisting the guard into the handler dispatcher so any future action gets it for free, but that would also pre-warm Chromium for assemble, which doesn't need it. The surgical copy keeps the cost where the work actually happens. Happy to switch direction if you'd prefer the dispatcher version.

The producer's probe stage launches Chromium when Plan has to resolve
browser-only data: root duration unknown, unresolved sub-compositions, or
data-hf-auto-start media. Only handleRenderChunk was setting
PRODUCER_HEADLESS_SHELL_PATH, so a cold Plan invocation launched
puppeteer-core with no executablePath and failed before writing plan.tar.gz.

Mirror the renderChunk env-var guard inside handlePlan so the bundled
Sparticuz binary gets resolved on the first Plan invocation and reused on
warm starts. The skipChromeResolution dep stays honored for SAM-local RIE
smokes.

A warm Lambda environment can mask this only if it previously served a
renderChunk from another execution and left the env var sticky. Within a
single Step Functions execution, Plan still runs before RenderChunks.

A new dispatch test exercises the guard path by pre-seeding
PRODUCER_HEADLESS_SHELL_PATH and asserting Plan does not overwrite it.
@kiyeonjeon21 kiyeonjeon21 force-pushed the fix/aws-lambda-handle-plan-chromium-init branch from 334227b to bc20b87 Compare May 24, 2026 07:22
@miguel-heygen miguel-heygen merged commit c9d5dc5 into heygen-com:main May 24, 2026
34 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

handlePlan never resolves Chromium, breaking probe-stage plans

2 participants