vitest-dev/vitest · error · Error

Access denied to "${path}". See Vite config documentation fo

Error message

Access denied to "${path}". See Vite config documentation for "server.fs": https://vitejs.dev/config/server-options.html#server-fs-strict.

What it means

`checkFileAccess` runs every snapshot/attachment/benchmark path through Vite's `isFileLoadingAllowed`, which enforces `server.fs.allow` and `server.fs.strict`. If the path falls outside the allowed roots, the call is rejected to prevent arbitrary filesystem reads/writes from the browser.

Source

Thrown at packages/browser/src/node/rpc.ts:120

          sessions.destroySession(sessionId)
        }
        // this will reject any hanging methods if there are any
        rpc.$close(
          new Error(`[vitest] Browser connection was closed while running tests. Was the page closed unexpectedly?`),
        )
      })
    })
  })

  // we don't throw an error inside a stream because this can segfault the process
  function error(err: Error) {
    console.error(err)
    vitest.state.catchError(err, 'RPC Error')
  }

  function checkFileAccess(path: string) {
    if (!isFileLoadingAllowed(vite.config, path)) {
      throw new Error(
        `Access denied to "${path}". See Vite config documentation for "server.fs": https://vitejs.dev/config/server-options.html#server-fs-strict.`,
      )
    }
  }

  function canWrite(project: TestProject) {
    return (
      project.config.api.allowWrite
      && project.vitest.config.api.allowWrite
    )
  }

  function isCdpAllowed(project: TestProject) {
    return (
      project.config.api.allowExec
      && project.vitest.config.api.allowExec
      && project.config.api.allowWrite
      && project.vitest.config.api.allowWrite

View on GitHub (pinned to d568f8ce37)

Solutions

  1. Add the offending root to `server.fs.allow` in the Vite/Vitest config: `server: { fs: { allow: ['/abs/path'] } }`.
  2. Make sure `resolveSnapshotPath` / custom attachment paths resolve under the project root.
  3. If intentional, set `server.fs.strict: false` (less safe — only when you trust all test code).
  4. On Windows, prefer forward-slash absolute paths to avoid drive-letter edge cases.

Example fix

// before
export default defineConfig({
  test: { server: { fs: { strict: true } } },
})

// after — explicitly allow the snapshot root
export default defineConfig({
  test: {
    server: { fs: { allow: ['/home/me/project', '/home/me/shared-snapshots'] } },
  },
})
Defensive patterns

Strategy: validation

Validate before calling

import { isFileLoadingAllowed } from 'vitest/node'

function assertFsAllowed(viteConfig: import('vite').InlineConfig, path: string): void {
  if (!isFileLoadingAllowed(viteConfig, path)) {
    throw new Error(`Path ${path} is outside server.fs.allow — add it or use a path under root`)
  }
}

Try / catch

try {
  await fs.writeFile(snapshotPath, content)
} catch (err) {
  if (err instanceof Error && /Access denied to/.test(err.message)) {
    // add the path to server.fs.allow, or move under root
  }
  throw err
}

Prevention

When it happens

Trigger: Any RPC method that touches the filesystem (`readSnapshotFile`, `saveSnapshotFile`, `removeSnapshotFile`, attachment recording, benchmark read/write) with a path outside Vite's `server.fs.allow` list while `server.fs.strict` is on (the default).

Common situations: Custom `resolveSnapshotPath` that resolves outside the workspace root; symlinked test files whose real path is outside root; monorepo where the test file is in one package but snapshots write to another; cross-drive paths on Windows.

Related errors


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