{"record":{"id":"6ea467508a0c2996","repo":"vitest-dev/vitest","slug":"cannot-modify-file-path-file-writing-is-disa","errorCode":null,"errorMessage":"Cannot modify file \"${path}\". File writing is disabled because the server is exposed to the internet, see https://vitest.dev/config/browser/api.","messagePattern":"Cannot modify file \"(.+?)\"\\. File writing is disabled because the server is exposed to the internet, see https://vitest\\.dev/config/browser/api\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/browser/src/node/utils.ts","lineNumber":114,"sourceCode":"export function slash(path: string): string {\n  return path.replace(/\\\\/g, '/').replace(/\\/+/g, '/')\n}\n\nexport function assertBrowserFileAccess(project: TestProject, path: string): void {\n  const normalized = slash(path)\n  if (\n    !isFileLoadingAllowed(project.vite.config, normalized)\n    && !isFileLoadingAllowed(project.vitest.vite.config, normalized)\n  ) {\n    throw new Error(\n      `Access denied to \"${path}\". See Vite config documentation for \"server.fs\": https://vitejs.dev/config/server-options.html#server-fs-strict.`,\n    )\n  }\n}\n\nexport function assertBrowserApiWrite(project: TestProject, path: string): void {\n  if (!project.config.api.allowWrite || !project.vitest.config.api.allowWrite) {\n    throw new Error(\n      `Cannot modify file \"${path}\". File writing is disabled because the server is exposed to the internet, see https://vitest.dev/config/browser/api.`,\n    )\n  }\n}\n","sourceCodeStart":96,"sourceCodeEnd":119,"githubUrl":"https://github.com/vitest-dev/vitest/blob/1fa9837ec26533512fdcad8baebf249771bd340a/packages/browser/src/node/utils.ts#L96-L119","documentation":"Thrown by assertBrowserApiWrite when either project.config.api.allowWrite or project.vitest.config.api.allowWrite is false. This is a deliberate security guard: when the browser API server could be exposed to the internet, file writes from the browser UI are blocked to prevent remote code/asset tampering.","triggerScenarios":"assertBrowserApiWrite(project, path) is invoked by a browser-API write operation (e.g. updating a snapshot or file from the UI) and either allowWrite flag is falsy.","commonSituations":"Running the browser UI on a host reachable from the internet (api.host not loopback) where allowWrite defaults off; a CI dashboard exposing the UI publicly; wanting to edit tests from the browser panel in such a setup.","solutions":["If on a trusted/private network, set test.api.allowWrite: true explicitly in config after confirming the listener is not publicly reachable.","Bind the API/UI to loopback (api.host: '127.0.0.1') so the default posture stays safe and writes are not gated.","Do not enable allowWrite when the server is exposed — restructure so writes happen on the developer's machine instead."],"exampleFix":"// before: server exposed, writes blocked\nexport default defineConfig({ test: { api: { port: 51204 } } })\n// after: trusted loopback, writes allowed\nexport default defineConfig({ test: { api: { host: '127.0.0.1', port: 51204, allowWrite: true } } })","handlingStrategy":"validation","validationCode":"// Ensure writes are only attempted when the API is configured for them.\nfunction canWriteFromBrowser(cfg) {\n  return cfg.test?.api?.allowWrite === true && cfg.test?.api?.host !== '0.0.0.0'\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Default the browser API/UI to loopback (api.host: '127.0.0.1').","Only enable api.allowWrite on trusted, non-public networks.","Never expose the browser UI to the internet with allowWrite enabled."],"tags":["browser","security","api","config"],"backgroundTag":null,"analyzedSha":"1fa9837ec26533512fdcad8baebf249771bd340a","analyzedAt":"2026-08-11T16:11:39.638Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}