heygen-com/hyperframes · critical · ChromeBinaryUnavailableError

[chromium] Chrome binary unavailable (source=${source}): @sp

Error message

[chromium] Chrome binary unavailable (source=${source}): @sparticuz/chromium.executablePath() returned a falsy value or a path that doesn't exist on disk. This typically happens after a chunk hits `Sandbox.Timedout` mid-extraction and leaves /tmp in a wedged state — subsequent invocations land on the same warm instance and never re-extract. Recycle the function (e.g. `aws lambda update-function-configuration ... --environment ...` with a bumped marker var, or redeploy via `hyperframes lambda deploy --skip-build`) to force fresh execution environments. Tracking: investigate the upstream wedge so this auto-recovers.

What it means

A `ChromeBinaryUnavailableError` thrown when `@sparticuz/chromium`'s `executablePath()` resolves to a non-string (null/undefined/empty). The resolver refuses to forward a falsy value to puppeteer-core because puppeteer would surface an unrelated-looking assertion instead. The hint points at a known `Sandbox.Timedout` mid-extraction wedge that leaves `/tmp` dirty on warm Lambda instances.

Source

Thrown at packages/aws-lambda/src/chromium.ts:104

 *
 * For `"chrome-headless-shell"`: read the path from
 * `HYPERFRAMES_LAMBDA_CHROME_PATH`. Throws if absent or non-existent so a
 * misconfigured deploy fails loudly at boot rather than at first frame.
 */
// fallow-ignore-next-line complexity
export async function resolveChromeExecutablePath(): Promise<string> {
  const source = resolveChromeSource();
  if (source === "sparticuz") {
    const mod = await loadSparticuzChromium();
    const path = await mod.executablePath();
    // Guard against the wedge described in ChromeBinaryUnavailableError.
    // sparticuz's contract is "return the path to a usable binary" — when
    // it returns null/undefined/"" we can't hand that to puppeteer-core
    // (which will throw an unrelated-looking assertion). Same when the
    // returned path doesn't exist (extraction failed but the function
    // call returned).
    if (!path || typeof path !== "string") {
      throw new ChromeBinaryUnavailableError(source, null, SPARTICUZ_WEDGE_HINT);
    }
    if (!existsSync(path)) {
      throw new ChromeBinaryUnavailableError(source, path, SPARTICUZ_WEDGE_HINT);
    }
    return path;
  }
  const explicit = process.env.HYPERFRAMES_LAMBDA_CHROME_PATH;
  if (!explicit) {
    throw new ChromeBinaryUnavailableError(
      source,
      null,
      "HYPERFRAMES_LAMBDA_CHROME_SOURCE=chrome-headless-shell requires " +
        "HYPERFRAMES_LAMBDA_CHROME_PATH to be set to the absolute path of the bundled binary.",
    );
  }
  if (!existsSync(explicit)) {
    throw new ChromeBinaryUnavailableError(
      source,

View on GitHub (pinned to c2996c8626)

Solutions

  1. Recycle the Lambda execution environment: `aws lambda update-function-configuration --function-name <fn> --environment Variables=<existing>,HF_RECYCLE_MARKER=$(date +%s)` to force fresh containers.
  2. Redeploy with `hyperframes lambda deploy --skip-build` to get new instances.
  3. Bump the Lambda timeout / memory so extraction completes before `Sandbox.Timedout`.
  4. Pin or upgrade @sparticuz/chromium to a known-good version for your Lambda node runtime.
  5. Investigate the upstream wedge so warm instances auto-recover (tracking note in the hint).

Example fix

# before: warm instance wedged
aws lambda invoke --function-name my-fn out.json
# after: recycle to force re-extraction
aws lambda update-function-configuration --function-name my-fn --environment "Variables={HF_RECYCLE_MARKER=$(date +%s)}"
Defensive patterns

Strategy: retry

Type guard

function isUsableChromiumPath(path: unknown): path is string {
  return typeof path === "string" && path.length > 0;
}

Try / catch

import { ChromeBinaryUnavailableError } from "@hyperframes/aws-lambda";
try {
  const p = await resolveChromeExecutablePath();
} catch (err) {
  if (err instanceof ChromeBinaryUnavailableError && err.source === "sparticuz") {
    // recycle the environment via update-function-configuration / redeploy, then retry
  }
  throw err;
}

Prevention

When it happens

Trigger: `resolveChromeExecutablePath()` with `HYPERFRAMES_LAMBDA_CHROME_SOURCE=sparticuz` where `mod.executablePath()` returns null/undefined/"" — typically because a prior extraction timed out and the warm container never re-extracts.

Common situations: Lambda warm instance wedged after a `Sandbox.Timedout` mid-extraction; corrupted/incomplete `/tmp/chromium` extraction from a previous invocation; @sparticuz/chromium version regression that changed `executablePath()` semantics.

Understand the failure class

Related errors


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