microsoft/playwright · error · Error

Cannot find Firefox installation for channel '${name}' at th

Error message

Cannot find Firefox installation for channel '${name}' at the standard system paths. Tried paths:
  ${prefixes.map(p => path.join(p, suffix)).join('\n  ')}

What it means

Thrown by the bidi-Firefox channel resolver when the current platform IS supported (suffix exists) but none of the probed prefix+suffix paths are accessible — Firefox is not installed at the standard system locations. Unlike the Chromium variant, this message lists every path that was tried. Only thrown when shouldThrow is true.

Source

Thrown at packages/playwright-core/src/server/registry/index.ts:879

          throw new Error(`Firefox distribution '${name}' is not supported on ${process.platform}`);
        return undefined;
      }
      const prefixes = (process.platform === 'win32' ? [
        process.env.LOCALAPPDATA,
        process.env.PROGRAMFILES,
        process.env['PROGRAMFILES(X86)'],
        // In some cases there is no PROGRAMFILES/(86) env var set but HOMEDRIVE is set.
        process.env.HOMEDRIVE + '\\Program Files',
        process.env.HOMEDRIVE + '\\Program Files (x86)',
      ].filter(Boolean) : ['']) as string[];

      for (const prefix of prefixes) {
        const executablePath = path.join(prefix, suffix);
        if (canAccessFile(executablePath))
          return executablePath;
      }
      if (shouldThrow)
        throw new Error(`Cannot find Firefox installation for channel '${name}' at the standard system paths. ${`Tried paths:\n  ${prefixes.map(p => path.join(p, suffix)).join('\n  ')}`}`);
      return undefined;
    };
    return {
      name,
      browserName: 'firefox',
      directory: undefined,
      executablePath: () => executablePath('', false),
      executablePathOrDie: (sdkLanguage: string) => executablePath(sdkLanguage, true)!,
      installType: 'none',
      _validateHostRequirements: () => Promise.resolve(),
      _isHermeticInstallation: true,
      _install: install,
    };
  }

  executables(): Executable[] {
    return this._executables;
  }

View on GitHub (pinned to c8fc3bf8d3)

Solutions

  1. Install Firefox at a standard system path (apt-get install firefox / brew install --cask firefox / official installer).
  2. Switch to Playwright's hermetic bundled firefox: 'npx playwright install firefox'.
  3. Inspect the 'Tried paths' list in the message and either place a binary/symlink at the first path or correct the install location.

Example fix

// before — system firefox missing
const browser = await firefox.launch();

// after — hermetic install
// shell: npx playwright install firefox
const browser = await firefox.launch();
Defensive patterns

Strategy: try-catch

Validate before calling

import { registry } from 'playwright-core/lib/server/registry';

const exec = registry.findExecutable('firefox');
const installed = !!exec?.executablePath(); // non-throwing
if (!installed) console.warn('Run: npx playwright install firefox');

Type guard

function isFirefoxInstalled(): boolean {
  const exec = registry.findExecutable('firefox');
  return !!exec?.executablePath();
}

Try / catch

try {
  browser = await firefox.launch();
} catch (e) {
  if (/Cannot find Firefox installation/.test(e.message))
    browser = await chromium.launch(); // cross-engine fallback
  else throw e;
}

Prevention

When it happens

Trigger: Calling executablePathOrDie for the bidi-Firefox channel when the OS is in the lookAt map but canAccessFile returns false for every prefix path. Typical when launching Firefox in BiDi mode against a system install that is absent.

Common situations: Clean CI runner or container where Firefox was never installed; Firefox installed via snap/flatpak to a path Playwright does not probe; stale PATH but binary moved.

Related errors


AI-assisted analysis of microsoft/playwright@c8fc3bf8d3 (2026-08-12). Data as JSON: /api/errors/de6d65288be5b50d. Report an issue: GitHub.