heygen-com/hyperframes · critical · ChromeBinaryUnavailableError

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

Error message

[chromium] Chrome binary unavailable (source=${source}): HYPERFRAMES_LAMBDA_CHROME_PATH=${JSON.stringify(explicit)} does not exist on disk.

What it means

A `ChromeBinaryUnavailableError` thrown when the chrome-headless-shell source is configured and `HYPERFRAMES_LAMBDA_CHROME_PATH` is set, but the referenced path does not exist on disk. The hint echoes the offending path (JSON-stringified) so the operator can spot quoting/leading-space errors in the env var.

Source

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

    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,
      explicit,
      `HYPERFRAMES_LAMBDA_CHROME_PATH=${JSON.stringify(explicit)} does not exist on disk.`,
    );
  }
  return explicit;
}

/**
 * Resolve the Chromium launch args for the selected source. For
 * `@sparticuz/chromium` we forward `chromium.args` (Lambda-tuned defaults
 * — single-process, no-sandbox, /tmp paths). For the shell fallback the
 * engine's own arg builder owns it; we return an empty array so the
 * engine's defaults apply.
 */
export async function resolveChromeArgs(): Promise<string[]> {
  if (resolveChromeSource() !== "sparticuz") return [];
  const mod = await loadSparticuzChromium();

View on GitHub (pinned to c2996c8626)

Solutions

  1. Inspect the value echoed in the message for stray quotes, spaces, or a relative path; it must be absolute.
  2. Re-build the zip and confirm the binary is present at the configured path (unzip and `ls` /var/task/bin).
  3. Match the binary's architecture to the Lambda's `arch` setting (x86_64 vs arm64).
  4. Use `aws lambda update-function-code --zip-file` to deploy a corrected bundle.

Example fix

# before
HYPERFRAMES_LAMBDA_CHROME_PATH="/var/task/chrome-headless-shell"  # quotes leak into value
# after
HYPERFRAMES_LAMBDA_CHROME_PATH=/var/task/bin/chrome-headless-shell
Defensive patterns

Strategy: validation

Validate before calling

import { existsSync } from "node:fs";
function assertChromePathExists(): void {
  const p = process.env.HYPERFRAMES_LAMBDA_CHROME_PATH;
  if (p && !existsSync(p)) {
    throw new Error(`HYPERFRAMES_LAMBDA_CHROME_PATH does not exist: ${JSON.stringify(p)}`);
  }
}
// run before resolveChromeExecutablePath

Prevention

When it happens

Trigger: `resolveChromeExecutablePath()` with `HYPERFRAMES_LAMBDA_CHROME_PATH` set to a path that `existsSync` reports missing — wrong path, binary not bundled into the zip, or a path with stray whitespace/quotes from env interpolation.

Common situations: build-zip.ts placed the binary at a different path than the env var; `HYPERFRAMES_LAMBDA_CHROME_PATH` wrapped in literal quotes that became part of the value; deploying a different architecture zip (arm64 vs x86_64) where the binary path differs.

Related errors


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