microsoft/playwright · critical · Error
Cannot launch Firefox with relative home directory. Did you
Error message
Cannot launch Firefox with relative home directory. Did you set ${os.platform() === 'win32' ? 'USERPROFILE' : 'HOME'} to a relative path? What it means
Before launching Firefox, Playwright checks `os.homedir()` is absolute because Firefox (via its launcher/crashreporter) misbehaves or crashes with a relative HOME. The message names the correct env var per platform (USERPROFILE on Windows, HOME elsewhere).
Source
Thrown at packages/playwright-core/src/server/bidi/bidiFirefox.ts:57
override executablePath(): string {
return '';
}
override async connectToTransport(transport: ConnectionTransport, options: BrowserOptions): Promise<BidiBrowser> {
return BidiBrowser.connect(this.attribution.playwright, transport, options);
}
override doRewriteStartupLog(logs: string): string {
if (logs.includes(`as root in a regular user's session is not supported.`))
logs = '\n' + wrapInASCIIBox(`Firefox is unable to launch if the $HOME folder isn't owned by the current user.\nWorkaround: Set the HOME=/root environment variable${process.env.GITHUB_ACTION ? ' in your GitHub Actions workflow file' : ''} when running Playwright.`, 1);
if (logs.includes('no DISPLAY environment variable specified'))
logs = '\n' + wrapInASCIIBox(kNoXServerRunningError, 1);
return logs;
}
override amendEnvironment(env: NodeJS.ProcessEnv): NodeJS.ProcessEnv {
if (!path.isAbsolute(os.homedir()))
throw new Error(`Cannot launch Firefox with relative home directory. Did you set ${os.platform() === 'win32' ? 'USERPROFILE' : 'HOME'} to a relative path?`);
env = {
...env,
'MOZ_CRASHREPORTER': '1',
'MOZ_CRASHREPORTER_NO_REPORT': '1',
'MOZ_CRASHREPORTER_SHUTDOWN': '1',
};
if (os.platform() === 'linux') {
// Always remove SNAP_NAME and SNAP_INSTANCE_NAME env variables since they
// confuse Firefox: in our case, builds never come from SNAP.
// See https://github.com/microsoft/playwright/issues/20555
return { ...env, SNAP_NAME: undefined, SNAP_INSTANCE_NAME: undefined };
}
return env;
}
override attemptToGracefullyCloseBrowser(transport: ConnectionTransport) {View on GitHub (pinned to c8fc3bf8d3)
Solutions
- Set HOME to an absolute path: `export HOME=/root` (Linux) or fix USERPROFILE (Windows)
- In GitHub Actions add `env: { HOME: '/root' }` to the step
- In Dockerfiles use `ENV HOME=/root`
- Verify before launch: `node -e "console.log(require('os').homedir())"`
Example fix
// before (env: HOME=relative/path) const b = await firefox.launch(); // after // shell: export HOME=/root // or in CI yaml: env: HOME: /root const b = await firefox.launch();
Defensive patterns
Strategy: validation
Validate before calling
import path from 'path';
import os from 'os';
function ensureAbsoluteHome(): void {
const home = os.homedir();
if (!path.isAbsolute(home)) {
throw new Error(
`HOME must be absolute (got '${home}'). Run: export HOME=$HOME on POSIX or fix USERPROFILE on Windows.`
);
}
}
ensureAbsoluteHome();
await firefox.launch(); Prevention
- In Docker/CI set `ENV HOME=/root` or `export HOME=$HOME`
- Verify with `node -e "console.log(require('os').homedir())"` in your environment
- Run Firefox launch under the same UID that owns $HOME
When it happens
Trigger: `firefox.launch()` or any Firefox launch (incl. BiDi) when HOME (Linux/macOS) or USERPROFILE (Windows) resolves to a relative path via `os.homedir()`.
Common situations: Misconfigured Docker/CI images where HOME is unset or relative; shell rc files exporting a relative HOME; systemd units with `HOME=.`; WSL/Windows env mixups; containers running as a UID with no passwd entry.
Related errors
- Arguments can not specify page to be opened
- Failed to launch the browser process.\nBrowser logs:\n${upda
- fs is not available in the browser
- path is not available in the browser
- No devices found
AI-assisted analysis of microsoft/playwright@c8fc3bf8d3 (2026-08-12).
Data as JSON: /api/errors/c43b1f3e2acac76b.
Report an issue: GitHub.