vitest-dev/vitest · error · Error
"Istanbul" coverage provider is not compatible with "experim
Error message
"Istanbul" coverage provider is not compatible with "experimental.viteModuleRunner: false". Please, enable "viteModuleRunner" or switch to "v8" coverage provider.
What it means
Istanbul coverage instruments source by transforming modules, which requires Vitest's Vite module runner. When `experimental.viteModuleRunner` is explicitly `false`, Istanbul cannot hook module loading to inject instrumentation, so the check at resolveConfig.ts:451 forbids the combination.
Source
Thrown at packages/vitest/src/node/config/resolveConfig.ts:452
// if `instances` were defined, but now they are empty,
// let's throw an error because the filter is invalid
if (!browser.instances.length) {
throw new Error([
`"browser.instances" was set in the config, but the array is empty. Define at least one browser config.`,
` The "browser.name" was set to "${browser.name}" which filtered all configs (${instances.map(c => c.browser).join(', ')}). Did you mean to use another name?`,
].join(''))
}
}
browser.instances.forEach((instance) => {
instance.name ??= resolved.name
? `${resolved.name} (${instance.browser})`
: instance.browser
})
}
if (resolved.coverage.enabled && resolved.coverage.provider === 'istanbul' && resolved.experimental?.viteModuleRunner === false) {
throw new Error(`"Istanbul" coverage provider is not compatible with "experimental.viteModuleRunner: false". Please, enable "viteModuleRunner" or switch to "v8" coverage provider.`)
}
if (browser.enabled && resolved.detectAsyncLeaks) {
logger.console.warn(c.yellow('The option "detectAsyncLeaks" is not supported in browser mode and will be ignored.'))
}
resolved.coverage.reporter = resolveCoverageReporters(resolved.coverage.reporter)
if (isAgent) {
// default to `skipFull` and add `text-summary` reporter when `text` reporter is used on agents
const text = resolved.coverage.reporter.find(([name]) => name === 'text')
const textSummary = resolved.coverage.reporter.find(([name]) => name === 'text-summary')
if (text) {
(text as any)[1] = { skipFull: true, ...text[1] as any }
if (!textSummary) {
resolved.coverage.reporter.push(['text-summary', {}])
}
}
}View on GitHub (pinned to d568f8ce37)
Solutions
- Remove the `experimental.viteModuleRunner: false` override so Istanbul can instrument modules.
- Switch coverage to the v8 provider, which does not require the module runner: `coverage: { provider: 'v8' }`.
- If you must keep viteModuleRunner off, disable coverage entirely.
Example fix
// before
export default defineConfig({ test: { coverage: { enabled: true, provider: 'istanbul' }, experimental: { viteModuleRunner: false } } })
// after
export default defineConfig({ test: { coverage: { enabled: true, provider: 'v8' } } }) Defensive patterns
Strategy: type-guard
Validate before calling
function assertCoverageCompatible(config: any) {
if (config?.coverage?.enabled && config.coverage.provider === 'istanbul' && config.experimental?.viteModuleRunner === false) {
throw new Error('Istanbul coverage requires viteModuleRunner; switch to v8 or remove the experimental flag.')
}
} Type guard
function isCoverageConfigValid(config: any): boolean {
return !(config?.coverage?.enabled && config.coverage.provider === 'istanbul' && config.experimental?.viteModuleRunner === false)
} Prevention
- Prefer the v8 provider unless you need Istanbul's native-ES instrumented reports.
- Do not set experimental.viteModuleRunner: false unless you understand the trade-offs.
- Document why viteModuleRunner is disabled if you must disable it.
When it happens
Trigger: Set `coverage: { enabled: true, provider: 'istanbul' }` together with `experimental: { viteModuleRunner: false }`.
Common situations: Opting out of the Vite module runner for performance/compat reasons while still wanting Istanbul coverage; copying an experimental flag from a workaround.
Related errors
- Failed to load ${CoverageProviderMap[provider]}. Default exp
- Something removed the coverage directory "${coverageFilesDir
- Something removed the coverage directory "${coverageFilesDir
- V8 provider missing inspector session.
- You cannot set "coverage.reportsDirectory" as ${reportsDirec
AI-assisted analysis of vitest-dev/vitest@d568f8ce37 (2026-08-03).
Data as JSON: /data/errors/d8004f0d5e1199a1.json.
Report an issue: GitHub.