microsoft/playwright · error · Error

--output-dir cannot point to a system directory: ${path.reso

Error message

--output-dir cannot point to a system directory: ${path.resolve(outputDir)}.

What it means

Thrown by `validateOutputDir` (called from both MCP and CLI config resolution) when the resolved `--output-dir` is a system directory (root, Windows system dirs, `/usr`, etc.). Writing artifacts (screenshots, traces, recordings) into a system directory is unsafe, so config validation rejects it.

Source

Thrown at packages/playwright-core/src/tools/mcp/config.ts:151

  let result = defaultConfig;
  result = mergeConfig(result, resolveConfigPaths(configInFile, configDir));
  result = mergeConfig(result, resolveConfigPaths(envOverrides, process.cwd()));
  result = mergeConfig(result, resolveConfigPaths(cliOverrides, process.cwd()));

  const browser = await validateBrowserConfig(result.browser);
  if (browser.launchOptions.headless === undefined)
    browser.launchOptions.headless = os.platform() === 'linux' && !process.env.DISPLAY;

  validateOutputDir(result.outputDir);

  return { ...result, browser, configFile };
}

function validateOutputDir(outputDir: string | undefined) {
  if (!outputDir)
    return;
  if (isSystemDirectory(outputDir))
    throw new Error(`--output-dir cannot point to a system directory: ${path.resolve(outputDir)}.`);
}

export async function resolveCLIConfigForCLI(daemonProfilesDir: string, sessionName: string, options: any, env?: NodeJS.ProcessEnv): Promise<FullConfig> {
  const config = options.config ? path.resolve(options.config) : undefined;
  try {
    const defaultConfigFile = path.resolve('.playwright', 'cli.config.json');
    if (!config && fs.existsSync(defaultConfigFile))
      options.config = defaultConfigFile;
  } catch {
  }

  const daemonOverrides = configFromCLIOptions({
    endpoint: options.endpoint,
    cdpEndpoint: options.cdp,
    config: options.config,
    browser: options.browser,
    device: options.device,
    headless: options.headed ? false : undefined,

View on GitHub (pinned to c8fc3bf8d3)

Solutions

  1. Point `--output-dir` at a writable, non-system directory (e.g. `./test-results`, `~/artifacts`).
  2. If the value comes from an env var, set it to a concrete project-relative path.
  3. Verify the resolved absolute path (shown in the error) is what you intended.

Example fix

# before
--output-dir /
# after
--output-dir ./test-results
Defensive patterns

Strategy: validation

Validate before calling

import { isSystemDirectory } from '@utils/fileUtils';
function assertOutputDir(dir: string | undefined) {
  if (dir && isSystemDirectory(dir))
    throw new Error(`output-dir is a system directory: ${dir}; choose a project path.`);
}

Prevention

When it happens

Trigger: Setting `--output-dir /`, `--output-dir /usr`, `--output-dir C:\Windows`, or any path that `isSystemDirectory` flags, in either the MCP server config or the CLI daemon config. The check runs on every config resolution path.

Common situations: Defaulting `--output-dir` to an env var that resolves to `/`; passing a bare `/` by mistake; a misconfigured config file whose `outputDir` points at a system path; relative paths that resolve unexpectedly to a system dir from an odd cwd.

Related errors


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