microsoft/playwright · error · Error
Cannot find Firefox installation for channel
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.
Solutions
- Install Firefox at a standard system path (apt-get install firefox / brew install --cask firefox / official installer).
- Switch to Playwright's hermetic bundled firefox: 'npx playwright install firefox'.
- 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
- Install Firefox at a standard system path or use the bundled build.
- On Linux, prefer apt/brew installs over snap which may place binaries outside probed paths.
- Add a pre-launch probe in test bootstrap to fail fast with an actionable message.
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
- Firefox distribution
- Cannot serialize result: object reference chain is too long.
- Chromium distribution
- JSHandle is not a DOM node handle
- Method not implemented.
AI-assisted analysis of microsoft/playwright@500c9c822c (2026-08-12).
Data as JSON: /api/errors/de6d65288be5b50d.
Report an issue: GitHub.
Appendix: 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 500c9c822c)