vitest-dev/vitest · error · Error

Something removed the coverage directory "${coverageFilesDir

Error message

Something removed the coverage directory "${coverageFilesDirectory}" Vitest created earlier. Make sure you are not running multiple Vitests with the same "coverage.reportsDirectory" at the same time.

What it means

Thrown by the Istanbul coverage provider's writeCoverageFile when writeFile fails AND the coverage directory no longer exists. The directory is created earlier in the run; its disappearance mid-run signals an external process (typically a concurrent Vitest) deleted it.

Source

Thrown at packages/coverage-istanbul/src/commands.ts:28

    const provider = context.project.vitest.coverageProvider as IstanbulCoverageProvider

    return writeCoverageFile(provider.coverageFilesDirectory, coverage)
  },
}

export async function writeCoverageFile(coverageFilesDirectory: string, coverage: unknown): Promise<string> {
  // Write results on file system directly and transfer only the filename over RPC
  const filename = resolve(
    coverageFilesDirectory,
    `coverage-${randomUUID()}.json`,
  )

  try {
    await writeFile(filename, JSON.stringify(coverage), 'utf-8')
  }
  catch (error) {
    if (!existsSync(coverageFilesDirectory)) {
      throw new Error(
        `Something removed the coverage directory "${coverageFilesDirectory}" Vitest created earlier. Make sure you are not running multiple Vitests with the same "coverage.reportsDirectory" at the same time.`,
        { cause: error },
      )
    }

    throw error
  }

  return filename
}

View on GitHub (pinned to d568f8ce37)

Solutions

  1. Give each concurrent Vitest run a distinct coverage.reportsDirectory.
  2. Run coverage jobs sequentially instead of in parallel.
  3. Remove any script/watcher that deletes the reports directory during the run.

Example fix

// before — two jobs share the default 'coverage/'
// job A: vitest --coverage
// job B: vitest --coverage (browser)
// after
// job A: vitest --coverage --coverage.reportsDirectory=coverage/unit
// job B: vitest --coverage --coverage.reportsDirectory=coverage/browser
Defensive patterns

Strategy: validation

Validate before calling

import { existsSync, mkdirSync } from 'node:fs'
// ensure reportsDirectory exists right before writing
if (!existsSync(coverageFilesDirectory)) {
  mkdirSync(coverageFilesDirectory, { recursive: true })
}

Try / catch

try {
  await writeCoverageFile(dir, coverage)
} catch (e) {
  if (/removed the coverage directory/i.test(String((e as Error).message))) {
    // retry once after recreating the dir
    mkdirSync(dir, { recursive: true })
    return writeCoverageFile(dir, coverage)
  }
  throw e
}

Prevention

When it happens

Trigger: Browser-mode coverage writes a coverage-<uuid>.json into coverageFilesDirectory; the write throws ENOENT and existsSync(coverageFilesDirectory) is false, triggering this wrapper error with the original as cause.

Common situations: Two Vitest processes sharing the same coverage.reportsDirectory (e.g. unit + browser CI jobs in parallel); a watch/clean step or coverage-cleaning script racing with the run; running coverage in a container whose tmp dir is reaped.

Related errors


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