heygen-com/hyperframes · error · Error

Missing browser script ${name}

Error message

Missing browser script ${name}

What it means

Thrown by loadBrowserScript() in packages/cli/src/commands/layout.ts:288. It looks for the named asset (e.g. layout-audit.browser.js) in two locations under __dirname — the current dir and a `commands/` subdir — and throws if neither exists. These .browser.js files are build artifacts that must be copied into the package output; they are not in the source tree at runtime.

Source

Thrown at packages/cli/src/commands/layout.ts:293

      duration,
      samples,
      transitionSamples,
      transitionSamplesDropped,
      rawIssues: dedupeLayoutIssues(issues),
      motionSamples,
    };
  } finally {
    await chromeBrowser?.close().catch(() => {});
    await server.close();
  }
}

export function loadBrowserScript(name: string): string {
  const candidates = [join(__dirname, name), join(__dirname, "commands", name)];
  for (const candidate of candidates) {
    if (existsSync(candidate)) return readFileSync(candidate, "utf-8");
  }
  throw new Error(`Missing browser script ${name}`);
}

function loadLayoutAuditScript(): string {
  return loadBrowserScript("layout-audit.browser.js");
}

async function collectLayoutIssues(
  page: import("puppeteer-core").Page,
  samples: number[],
  tolerance: number,
): Promise<LayoutIssue[]> {
  if (samples.length === 0) return [];
  await page.addScriptTag({ content: loadLayoutAuditScript() });

  const issues: LayoutIssue[] = [];
  for (const time of samples) {
    await seekCompositionTimeline(page, time, LAYOUT_SEEK_OPTIONS);
    const sampleIssues = await page.evaluate(

View on GitHub (pinned to c2996c8626)

Solutions

  1. Rebuild the CLI package (`bun run build`) and confirm the .browser.js file appears next to the compiled layout.js.
  2. If using workspace linking, run from the built dist directory rather than src, or rebuild after edits.
  3. Check the script name passed in matches an actual shipped asset (layout-audit.browser.js is the canonical one).
  4. Report a packaging bug if the asset is present in source build config but missing from the published tarball.

Example fix

# before: running from a stale/incomplete dist
hyperframes lint
# after: rebuild so the browser asset is copied next to layout.js
bun run build
hyperframes lint
Defensive patterns

Strategy: validation

Validate before calling

import { existsSync, readFileSync } from 'node:fs';
import { join } from 'node:path';

function loadScriptOrThrow(name: string, dir: string): string {
  const candidates = [join(dir, name), join(dir, 'commands', name)];
  const found = candidates.find(existsSync);
  if (!found) throw new Error(`Missing browser script ${name}; rebuild the CLI package.`);
  return readFileSync(found, 'utf-8');
}

Try / catch

try {
  loadBrowserScript('layout-audit.browser.js');
} catch (error) {
  if (/Missing browser script/.test(String(error))) {
    // rebuild and retry once
    childProcess.execSync('bun run build', { stdio: 'inherit' });
    loadBrowserScript('layout-audit.browser.js');
  } else throw error;
}

Prevention

When it happens

Trigger: Calling loadBrowserScript (directly or via loadLayoutAuditScript -> collectLayoutIssues during `hyperframes lint`/layout checks) when the .browser.js asset wasn't emitted into the dist dir, or when called with a name that doesn't correspond to a shipped script.

Common situations: Incomplete build (`bun run build` didn't copy the .browser.js asset); monorepo/workspace linking where __dirname resolves to src rather than dist; typo or wrong name passed to loadBrowserScript; stale dist from before the asset was added.

Related errors


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