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

View on GitHub (pinned to d568f8ce37)

Solutions

  1. Verify the root path exists and is a directory: `ls -la <root>`.
  2. Fix typos or make the root absolute and stable (e.g. `path.resolve(__dirname, 'src')`).
  3. Ensure any build step that creates the root runs before Vitest.
  4. 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

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.