vitest-dev/vitest · error

You cannot set "coverage.reportsDirectory" as

Error message

You cannot set "coverage.reportsDirectory" as ${reportsDirectory}. Vitest needs to be able to remove this directory before test run

What it means

Before each run Vitest clears the coverage `reportsDirectory` so stale data does not leak into the new report. If that directory resolves to the project root or `process.cwd()`, clearing it would delete the user's whole project. The guard compares the resolved path against `resolved.root` and `process.cwd()` and refuses rather than perform a destructive wipe.

Solutions

  1. Point `coverage.reportsDirectory` at a subfolder such as `./coverage`.
  2. If you need coverage artifacts at the root, post-process/copy them after the run instead of redirecting the directory.
  3. Confirm the resolved absolute path is neither `root` nor `cwd`.

Example fix

// before
test: { coverage: { reportsDirectory: '.' } }
// after
test: { coverage: { reportsDirectory: './coverage' } }
Defensive patterns

Strategy: validation

Validate before calling

import { resolve } from 'node:path'
const reportsDirectory = resolve(config.root ?? process.cwd(), config.test.coverage.reportsDirectory)
if (reportsDirectory === config.root || reportsDirectory === process.cwd()) {
  throw new Error(`coverage.reportsDirectory resolves to root: ${reportsDirectory}`)
}

Type guard

function isSafeReportsDirectory(dir: string, root: string, cwd: string): boolean {
  return dir !== root && dir !== cwd
}

Prevention

When it happens

Trigger: Setting `coverage.reportsDirectory: '.'`, `coverage.reportsDirectory: './'`, or pointing it at the same path as `root`/cwd.

Common situations: Trying to dump coverage at the repo root for convenience; a relative path that resolves to the root in CI but to a subfolder locally.

Related errors


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

Appendix: source

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

        resolved.coverage.reporter.push(['text-summary', {}])
      }
    }
  }
  if (resolved.coverage.changed === undefined && resolved.changed !== undefined) {
    resolved.coverage.changed = resolved.changed
  }

  if (resolved.coverage.enabled && resolved.coverage.reportsDirectory) {
    const reportsDirectory = resolve(
      resolved.root,
      resolved.coverage.reportsDirectory,
    )

    if (
      reportsDirectory === resolved.root
      || reportsDirectory === process.cwd()
    ) {
      throw new Error(
        `You cannot set "coverage.reportsDirectory" as ${reportsDirectory}. Vitest needs to be able to remove this directory before test run`,
      )
    }

    if (resolved.coverage.htmlDir) {
      resolved.coverage.htmlDir = resolve(
        resolved.root,
        resolved.coverage.htmlDir,
      )
    }

    // infer default htmlDir based on builtin reporter's html output location
    if (!resolved.coverage.htmlDir) {
      const htmlReporter = resolved.coverage.reporter.find(([name]) => name === 'html' || name === 'html-spa')
      if (htmlReporter) {
        const [, options] = htmlReporter
        const subdir = options && typeof options === 'object' && 'subdir' in options && typeof options.subdir === 'string'
          ? options.subdir

View on GitHub (pinned to 1fa9837ec2)