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

  1. Set HOME to an absolute path: `export HOME=/root` (Linux) or fix USERPROFILE (Windows)
  2. In GitHub Actions add `env: { HOME: '/root' }` to the step
  3. In Dockerfiles use `ENV HOME=/root`
  4. 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

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


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