pbakaus/impeccable · error

Browser script not found at ${browserScriptPath}

Error message

Browser script not found at ${browserScriptPath}

What it means

Thrown when the browser-engine URL detector cannot read the compiled detector script detect-antipatterns-browser.js, which it injects into the page via puppeteer's evaluateOnNewDocument. That file is a build artifact regenerated by `bun run build:browser`; it is not hand-authored. The path is resolved relative to the engine source so it must sit two directories up from detect-url.mjs.

Source

Thrown at cli/engine/engines/browser/detect-url.mjs:201

  }

  // Read the browser detection script — reuse it instead of reimplementing
  const browserScriptPath = path.resolve(
    path.dirname(fileURLToPath(import.meta.url)),
    '..',
    '..',
    'detect-antipatterns-browser.js'
  );
  let browserScript;
  try {
    browserScript = profileStep(profile, {
      engine: 'browser',
      phase: 'setup',
      ruleId: 'read-browser-script',
      target: url,
    }, () => fs.readFileSync(browserScriptPath, 'utf-8'));
  } catch {
    throw new Error(`Browser script not found at ${browserScriptPath}`);
  }

  // CI runners (GitHub Actions Ubuntu) block unprivileged user namespaces, so
  // Chrome can't initialize its sandbox there. Disable the sandbox only when
  // running in CI; local users keep the default hardened launch.
  const launchArgs = process.env.CI ? ['--no-sandbox', '--disable-setuid-sandbox'] : [];
  const browser = externalBrowser || await profileStepAsync(profile, {
    engine: 'browser',
    phase: 'load',
    ruleId: 'launch-browser',
    target: url,
  }, () => launchBrowser(puppeteer, { headless: options?.headless ?? true, args: launchArgs }));
  const page = await profileStepAsync(profile, {
    engine: 'browser',
    phase: 'load',
    ruleId: 'new-page',
    target: url,
  }, () => browser.newPage());

View on GitHub (pinned to d14711ae3d)

Solutions

  1. Run `bun run build:browser` (or the full `bun run build`) to regenerate cli/engine/detect-antipatterns-browser.js, then retry.
  2. Confirm the file exists at the printed browserScriptPath and is non-empty; the resolved path is in the error message.
  3. If you moved the engine files, update the path.resolve('..', '..', 'detect-antipatterns-browser.js') hop in detect-url.mjs to match the new depth.
  4. For published packages, ensure the build step runs before publish so the browser bundle ships in the tarball.

Example fix

// before — file missing, fs.readFileSync throws ENOENT, caught and re-thrown

// after — regenerate the artifact before running the URL detector
// $ bun run build:browser
// then:
const results = await detectUrl('https://example.com');
Defensive patterns

Strategy: validation

Validate before calling

import { existsSync } from 'node:fs';
import path from 'node:path';
const scriptPath = path.resolve(
  path.dirname(fileURLToPath(import.meta.url)), '..', '..', 'detect-antipatterns-browser.js'
);
if (!existsSync(scriptPath)) {
  throw new Error('Run `bun run build:browser` first to generate the detector script.');
}

Type guard

function browserBundleReady(scriptPath) {
  return existsSync(scriptPath) && statSync(scriptPath).size > 0;
}

Try / catch

try {
  await detectUrl(url, options);
} catch (err) {
  if (/Browser script not found/.test(err.message)) {
    console.error('Detector bundle missing. Run `bun run build:browser` and retry.');
  } else throw err;
}

Prevention

When it happens

Trigger: Running the URL detector from source (cli/engine/engines/browser/detect-url.mjs) before the browser bundle has been built, so detect-antipatterns-browser.js does not exist at ../detect-antipatterns-browser.js. Also fires if the file was gitignored/deleted or the working directory layout was reorganized so the relative resolution misses.

Common situations: Fresh clone where `bun run build` was never run; running the CLI out of dist/ vs source mismatch; a refactor that moved the engine directory without updating the path.resolve('../..' + filename) hop; CI that installs the npm package but only ships source, not the prebuilt browser bundle.

Related errors


AI-assisted analysis of pbakaus/impeccable@d14711ae3d (2026-08-13). Data as JSON: /api/errors/393b3c8a14cf84c7. Report an issue: GitHub.