{"record":{"id":"d73f83e8d6dd5b75","repo":"vitest-dev/vitest","slug":"access-denied-to-path-see-vite-config-docume","errorCode":null,"errorMessage":"Access denied to \"${path}\". See Vite config documentation for \"server.fs\": https://vitejs.dev/config/server-options.html#server-fs-strict.","messagePattern":"Access denied to \"(.+?)\"\\. See Vite config documentation for \"server\\.fs\": https://vitejs\\.dev/config/server-options\\.html#server-fs-strict\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/browser/src/node/rpc.ts","lineNumber":120,"sourceCode":"          sessions.destroySession(sessionId)\n        }\n        // this will reject any hanging methods if there are any\n        rpc.$close(\n          new Error(`[vitest] Browser connection was closed while running tests. Was the page closed unexpectedly?`),\n        )\n      })\n    })\n  })\n\n  // we don't throw an error inside a stream because this can segfault the process\n  function error(err: Error) {\n    console.error(err)\n    vitest.state.catchError(err, 'RPC Error')\n  }\n\n  function checkFileAccess(path: string) {\n    if (!isFileLoadingAllowed(vite.config, path)) {\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\n  function canWrite(project: TestProject) {\n    return (\n      project.config.api.allowWrite\n      && project.vitest.config.api.allowWrite\n    )\n  }\n\n  function isCdpAllowed(project: TestProject) {\n    return (\n      project.config.api.allowExec\n      && project.vitest.config.api.allowExec\n      && project.config.api.allowWrite\n      && project.vitest.config.api.allowWrite","sourceCodeStart":102,"sourceCodeEnd":138,"githubUrl":"https://github.com/vitest-dev/vitest/blob/1fa9837ec26533512fdcad8baebf249771bd340a/packages/browser/src/node/rpc.ts#L102-L138","documentation":"checkFileAccess calls Vite's isFileLoadingAllowed against the resolved vite config and throws when the path falls outside every allowed root. Vite's server.fs.strict mode (default true) restricts file access to files within server.fs.allow (default: the project workspace root and search-up workspace roots). This is the same guard Vite applies to /@fs/ imports.","triggerScenarios":"Any browser RPC that reads/writes a file (readFile, writeFile, snapshot operations, screenshot reads) with a path outside server.fs.allow: an absolute path in /tmp, a file in a sibling monorepo package not in the allow list, or a symlink that escapes the allow root.","commonSituations":"Storing snapshots/screenshots outside the project (e.g. a shared /tmp dir); monorepo where one package's tests reference another package outside the search-up workspace roots; running with a custom root that excludes the file; symlinks that resolve outside the allow list.","solutions":["Keep all browser-accessed files (snapshots, screenshots, fixtures) inside the project root.","If you need access outside the root, add the directory to server.fs.allow in your vite/vitest config.","Disable server.fs.strict only as a last resort and never on a network-exposed server.","Resolve symlinks before passing paths, and ensure the realpath is within an allowed root."],"exampleFix":"// before\nexport default defineConfig({ test: { server: { fs: { strict: true } } } })\n// path outside root -> access denied\n// after\nexport default defineConfig({ test: { server: { fs: { allow: [workspaceRoot, '/data/snapshots'] } } } })","handlingStrategy":"validation","validationCode":"import { isFileLoadingAllowed } from 'vite'\nfunction pathAllowed(viteConfig: any, path: string): boolean {\n  return isFileLoadingAllowed(viteConfig, path)\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep browser-accessed files inside the project root.","Extend server.fs.allow explicitly rather than disabling server.fs.strict.","Resolve symlinks before checking access."],"tags":["security","vite-fs","filesystem","config","access-control"],"backgroundTag":null,"analyzedSha":"1fa9837ec26533512fdcad8baebf249771bd340a","analyzedAt":"2026-08-11T16:11:39.638Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}