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
- Point `--output-dir` at a writable, non-system directory (e.g. `./test-results`, `~/artifacts`).
- If the value comes from an env var, set it to a concrete project-relative path.
- 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
- Use a project-relative, writable directory for --output-dir.
- Sanitize env-var-driven paths before passing them as output-dir.
- Confirm the resolved absolute path is intended before launch.
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
- Init script file does not exist: ${script}
- Init page file does not exist: ${page}
- "deviceScaleFactor" option is not supported with null "viewp
- "isMobile" option is not supported with null "viewport"
- geolocation.longitude: precondition -180 <= LONGITUDE <= 180
AI-assisted analysis of microsoft/playwright@c8fc3bf8d3 (2026-08-12).
Data as JSON: /api/errors/0ec0e6a08c0aa404.
Report an issue: GitHub.