vitest-dev/vitest · error · Error
Root path does not exist or is not a directory: ${resolved.r
Error message
Root path does not exist or is not a directory: ${resolved.root} What it means
Thrown during config resolution after a statSync on resolved.root returns no entry (or a non-directory). Vitest requires `test.root` (and the Vite root it derives from) to be an existing directory because that is where file discovery, transforms, and module resolution anchor. A missing or file-typed root is a hard failure.
Source
Thrown at packages/vitest/src/node/config/resolveConfig.ts:222
options.environment = 'happy-dom'
}
const resolved = deepMerge({}, configDefaults, options) as ResolvedConfig
resolved.root = viteConfig.root
// These options are resolved once for the whole run using the root config.
// Coverage is shared by reference: each project's setup/test/config files are
// appended to the same exclude list below, keeping them out of the report.
if (globalConfig) {
resolved.coverage = globalConfig.coverage
resolved.attachmentsDir = globalConfig.attachmentsDir
resolved.mergeReportsLabel = globalConfig.mergeReportsLabel
}
const rootStats = statSync(resolved.root, { throwIfNoEntry: false })
if (!rootStats?.isDirectory()) {
throw new Error(`Root path does not exist or is not a directory: ${resolved.root}`)
}
resolved.mode ??= viteConfig.mode ?? 'test'
if (resolved.retry && typeof resolved.retry === 'object' && typeof resolved.retry.condition === 'function') {
logger.warn(
c.yellow('Warning: retry.condition function cannot be used inside a config file. '
+ 'Use a RegExp pattern instead, or define the function in your test file.'),
)
resolved.retry = {
...resolved.retry,
condition: undefined,
}
}
if (options.pool && typeof options.pool !== 'string') {
resolved.pool = options.pool.nameView on GitHub (pinned to d568f8ce37)
Solutions
- Verify the root path exists and is a directory: `ls -la <root>`.
- Fix typos or make the root absolute and stable (e.g. `path.resolve(__dirname, 'src')`).
- Ensure any build step that creates the root runs before Vitest.
- If you moved/renamed a package, update `test.root` / `vite.root` accordingly.
Example fix
// before
export default defineConfig({ test: { root: './srcc' } })
// after
export default defineConfig({ test: { root: './src' } }) Defensive patterns
Strategy: validation
Validate before calling
import { statSync } from 'node:fs'
function assertRootDir(root: string) {
const s = statSync(root, { throwIfNoEntry: false })
if (!s?.isDirectory()) throw new Error(`root is not a directory: ${root}`)
} Prevention
- Make test.root / vite.root absolute and stable (path.resolve(__dirname, 'src')).
- Verify the directory exists before running Vitest, especially in CI after checkout.
- Guard against undefined/empty roots computed from env or moved files.
When it happens
Trigger: Setting `root` (or `test.root`) to a path that does not exist, is a file rather than a directory, or is a broken symlink. After deep-merging configDefaults with user options and assigning `resolved.root = viteConfig.root`, the code stats it; if `!rootStats?.isDirectory()`, it throws.
Common situations: Typo in the root path; root computed from a variable (env, dirname of a moved file) that is undefined/empty; running Vitest from a different cwd than expected; root pointing to a yet-to-be-created build output dir; monorepo where the package root was renamed.
AI-assisted analysis of vitest-dev/vitest@d568f8ce37 (2026-08-03).
Data as JSON: /data/errors/f766d446df79aaac.json.
Report an issue: GitHub.