vitest-dev/vitest · error · Error

Root path does not exist or is not a directory

Error message

Root path does not exist or is not a directory: ${resolved.root}

What it means

During config resolution Vitest `statSync`s the resolved `root` with `throwIfNoEntry: false` and requires the result to be a directory. If the path is missing, is a file, or is any non-directory entry, it throws with the resolved path so the user can see exactly what was checked.

Solutions

  1. Verify the path exists and is a directory: `ls -la <root>`.
  2. Use an absolute path or one resolvable from cwd; print `path.resolve(process.cwd(), root)` to confirm.
  3. If pointing at a monorepo package, set `root` to that package folder, not a config file.
  4. Create the missing directory or fix the typo in `vitest.config.ts` / `--root`.

Example fix

// before
export default defineConfig({ test: { root: './config' } }) // './config' is a file

// after
export default defineConfig({ test: { root: './tests' } }) // directory exists
Defensive patterns

Strategy: validation

Validate before calling

import { statSync } from 'node:fs'
import { resolve } from 'node:path'

function assertRootValid(rawRoot: string): string {
  const root = resolve(process.cwd(), rawRoot)
  const stats = statSync(root, { throwIfNoEntry: false })
  if (!stats?.isDirectory()) {
    throw new Error(`Root is not a directory: ${root}`)
  }
  return root
}

export default defineConfig({ test: { root: assertRootValid(configRoot) } })

Prevention

When it happens

Trigger: Setting `root: './nonexistent'`, `root: './vitest.config.ts'` (a file, not a dir), `root: ''` (resolves to cwd that may be invalid in some sandboxes), or a relative root that resolves against an unexpected cwd. Also triggered by `--root` CLI flag pointing outside the project.

Common situations: Monorepo where `root` should be a package path but is set to the workspace root that lacks the expected structure; typos in config; running Vitest from a different cwd than expected; CI checkout missing a directory.

Related errors


AI-assisted analysis of vitest-dev/vitest@1fa9837ec2 (2026-08-11). Data as JSON: /api/errors/f766d446df79aaac. Report an issue: GitHub.

Appendix: source

Thrown at packages/vitest/src/node/config/resolveConfig.ts:250

    viteConfig.test as UserConfig | undefined,
  )

  const resolved = deepMerge({}, configDefaults, options) as ResolvedConfig
  resolved.root = viteConfig.root
  resolved.providedOptions = providedOptions

  // 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.name

View on GitHub (pinned to 1fa9837ec2)