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
- Set test.api.allowWrite = true in your config if you trust the clients (e.g. local dev).
- Avoid file-writing browser commands; read needed data through the test runner instead.
- 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
- Set api.allowWrite only in trusted/local environments; keep it false when exposed publicly.
- Prefer read-only browser interactions; do writes in the Node test runner via commands.
- Document the security trade-off when enabling allowWrite for remote api access.
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
- Access denied to "${path}". See Vite config documentation fo
- Couldn't write file to fs
- Access denied to "${path}". See Vite config documentation fo
- Cannot use CDP because browser API write or exec operations
- ${name}Browser name is required. Please, set `test.browser.i
AI-assisted analysis of vitest-dev/vitest@d568f8ce37 (2026-08-03).
Data as JSON: /data/errors/6ea467508a0c2996.json.
Report an issue: GitHub.