vitest-dev/vitest · error · Error

Cannot modify file "${path}". File writing is disabled becau

Error message

Cannot modify file "${path}". File writing is disabled because the server is exposed to the internet, see https://vitest.dev/config/browser/api.

What it means

Thrown by assertBrowserApiWrite() when api.allowWrite is false on either the project config or the global Vitest config. Because the browser API server can be exposed to the network, file-writing browser commands (writeFile, removeFile, screenshots) are gated behind an explicit opt-in to prevent untrusted clients from mutating the host filesystem.

Source

Thrown at packages/browser/src/node/utils.ts:114

export function slash(path: string): string {
  return path.replace(/\\/g, '/').replace(/\/+/g, '/')
}

export function assertBrowserFileAccess(project: TestProject, path: string): void {
  const normalized = slash(path)
  if (
    !isFileLoadingAllowed(project.vite.config, normalized)
    && !isFileLoadingAllowed(project.vitest.vite.config, normalized)
  ) {
    throw new Error(
      `Access denied to "${path}". See Vite config documentation for "server.fs": https://vitejs.dev/config/server-options.html#server-fs-strict.`,
    )
  }
}

export function assertBrowserApiWrite(project: TestProject, path: string): void {
  if (!project.config.api.allowWrite || !project.vitest.config.api.allowWrite) {
    throw new Error(
      `Cannot modify file "${path}". File writing is disabled because the server is exposed to the internet, see https://vitest.dev/config/browser/api.`,
    )
  }
}

View on GitHub (pinned to d568f8ce37)

Solutions

  1. Set test.api.allowWrite = true in your config if you trust the clients (e.g. local dev).
  2. Avoid file-writing browser commands; read needed data through the test runner instead.
  3. If exposing the api publicly, keep allowWrite false and use a separate, authenticated upload path.

Example fix

// before
export default defineConfig({
  test: {
    browser: { enabled: true, api: { port: 3000 } }, // allowWrite defaults false
  },
})
// after
export default defineConfig({
  test: {
    browser: { enabled: true, api: { port: 3000, allowWrite: true } },
  },
})
Defensive patterns

Strategy: validation

Validate before calling

function canWrite(project: { config: { api: { allowWrite?: boolean } } }): boolean {
  return project.config.api.allowWrite === true
}
if (!canWrite(project)) {
  throw new Error('Enable test.api.allowWrite to use writeFile/removeFile in browser')
}

Try / catch

try {
  await writeFile(path, data)
} catch (e) {
  if (/File writing is disabled/i.test(String((e as Error).message))) {
    // fall back to reading data through the runner instead
  } else throw e
}

Prevention

When it happens

Trigger: Calling writeFile/removeFile (or a screenshot matcher that writes) from the browser while api.allowWrite is falsy. The check fires before any disk operation.

Common situations: Enabling the browser api host for remote/CI access but forgetting to set api.allowWrite=true; using page.writeFile() in tests without enabling the write permission; defaulting to a network-exposed api where allowWrite is intentionally off for safety.

Related errors


AI-assisted analysis of vitest-dev/vitest@d568f8ce37 (2026-08-03). Data as JSON: /data/errors/6ea467508a0c2996.json. Report an issue: GitHub.