heygen-com/hyperframes · error · Error

[BrowserManager] Chrome binary not found at PRODUCER_HEADLES

Error message

[BrowserManager] Chrome binary not found at PRODUCER_HEADLESS_SHELL_PATH="${envPath}". Run `hyperframes browser ensure` to re-download.

What it means

Thrown by resolveHeadlessShellPath() when the PRODUCER_HEADLESS_SHELL_PATH environment variable is set to a path that does not exist on disk (existsSync returns false). This env var is the second-highest priority in the Chrome binary resolution chain (after config.chromePath), so it explicitly overrides all other lookup paths — a stale value here prevents fallback.

Source

Thrown at packages/engine/src/services/browserManager.ts:189

  }
  return undefined;
}

/**
 * Resolve chrome-headless-shell binary for deterministic BeginFrame rendering.
 * Checks config.chromePath, then PRODUCER_HEADLESS_SHELL_PATH env var,
 * then the CLI browser override, HyperFrames' managed cache, and Puppeteer's cache.
 */
export function resolveHeadlessShellPath(
  config?: Partial<Pick<EngineConfig, "chromePath">>,
): string | undefined {
  if (config?.chromePath) {
    return config.chromePath;
  }
  if (process.env.PRODUCER_HEADLESS_SHELL_PATH) {
    const envPath = process.env.PRODUCER_HEADLESS_SHELL_PATH;
    if (!existsSync(envPath)) {
      throw new Error(
        `[BrowserManager] Chrome binary not found at PRODUCER_HEADLESS_SHELL_PATH="${envPath}". ` +
          "Run `hyperframes browser ensure` to re-download.",
      );
    }
    return envPath;
  }
  if (process.env.HYPERFRAMES_BROWSER_PATH) {
    const envPath = process.env.HYPERFRAMES_BROWSER_PATH;
    if (!existsSync(envPath)) {
      throw new Error(
        `[BrowserManager] Chrome binary not found at HYPERFRAMES_BROWSER_PATH="${envPath}". ` +
          "Run `hyperframes browser ensure` to re-download.",
      );
    }
    return envPath;
  }
  const home = homedir();
  return (

View on GitHub (pinned to c2996c8626)

Solutions

  1. Run hyperframes browser ensure to re-download the managed Chrome headless shell.
  2. Verify the path exists: ls -la $PRODUCER_HEADLESS_SHELL_PATH — fix or remove the env var if stale.
  3. If the env var is no longer needed, unset it to let resolution fall through to the managed cache or Puppeteer's cache.
  4. In Docker, ensure the Chrome binary is installed in the image at the path the env var declares.

Example fix

# before (stale env var)
export PRODUCER_HEADLESS_SHELL_PATH=/opt/chrome/chrome-headless-shell
# (file deleted after image rebuild)

# after (re-download or unset)
npx hyperframes browser ensure
# or: unset PRODUCER_HEADLESS_SHELL_PATH to fall through to cache
Defensive patterns

Strategy: validation

Validate before calling

import { existsSync } from 'fs';

function validateChromePath(): string | undefined {
  const envPath = process.env.PRODUCER_HEADLESS_SHELL_PATH;
  if (envPath && !existsSync(envPath)) {
    console.warn(`PRODUCER_HEADLESS_SHELL_PATH points to missing file: ${envPath}. Unsetting.`);
    delete process.env.PRODUCER_HEADLESS_SHELL_PATH;
  }
  return envPath && existsSync(envPath) ? envPath : undefined;
}

Try / catch

try {
  resolveHeadlessShellPath(config);
} catch (err) {
  if (err instanceof Error && err.message.includes('PRODUCER_HEADLESS_SHELL_PATH')) {
    // unset the stale env var and retry resolution
    delete process.env.PRODUCER_HEADLESS_SHELL_PATH;
    resolveHeadlessShellPath(config);
  }
  throw err;
}

Prevention

When it happens

Trigger: resolveHeadlessShellPath() is called during browser launch. The env var is set (non-empty string), so the code enters the env-check branch and calls existsSync(envPath). If the file was deleted, the path points to a different machine's layout, or the path is a stale Docker layer reference, the check fails.

Common situations: Docker/container image was rebuilt and the Chrome binary moved. The env var was set in CI config pointing to a path that only exists in a different image. Chrome was uninstalled or the cache was cleared. The path has a typo or uses a non-absolute relative path that resolves differently at runtime.

Related errors


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