{"id":"d8004f0d5e1199a1","repo":"vitest-dev/vitest","slug":"istanbul-coverage-provider-is-not-compatible-wit","errorCode":null,"errorMessage":"\"Istanbul\" coverage provider is not compatible with \"experimental.viteModuleRunner: false\". Please, enable \"viteModuleRunner\" or switch to \"v8\" coverage provider.","messagePattern":"\"Istanbul\" coverage provider is not compatible with \"experimental\\.viteModuleRunner: false\"\\. Please, enable \"viteModuleRunner\" or switch to \"v8\" coverage provider\\.","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/vitest/src/node/config/resolveConfig.ts","lineNumber":452,"sourceCode":"      // if `instances` were defined, but now they are empty,\n      // let's throw an error because the filter is invalid\n      if (!browser.instances.length) {\n        throw new Error([\n          `\"browser.instances\" was set in the config, but the array is empty. Define at least one browser config.`,\n          ` 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?`,\n        ].join(''))\n      }\n    }\n\n    browser.instances.forEach((instance) => {\n      instance.name ??= resolved.name\n        ? `${resolved.name} (${instance.browser})`\n        : instance.browser\n    })\n  }\n\n  if (resolved.coverage.enabled && resolved.coverage.provider === 'istanbul' && resolved.experimental?.viteModuleRunner === false) {\n    throw new Error(`\"Istanbul\" coverage provider is not compatible with \"experimental.viteModuleRunner: false\". Please, enable \"viteModuleRunner\" or switch to \"v8\" coverage provider.`)\n  }\n\n  if (browser.enabled && resolved.detectAsyncLeaks) {\n    logger.console.warn(c.yellow('The option \"detectAsyncLeaks\" is not supported in browser mode and will be ignored.'))\n  }\n\n  resolved.coverage.reporter = resolveCoverageReporters(resolved.coverage.reporter)\n  if (isAgent) {\n    // default to `skipFull` and add `text-summary` reporter when `text` reporter is used on agents\n    const text = resolved.coverage.reporter.find(([name]) => name === 'text')\n    const textSummary = resolved.coverage.reporter.find(([name]) => name === 'text-summary')\n    if (text) {\n      (text as any)[1] = { skipFull: true, ...text[1] as any }\n      if (!textSummary) {\n        resolved.coverage.reporter.push(['text-summary', {}])\n      }\n    }\n  }","sourceCodeStart":434,"sourceCodeEnd":470,"githubUrl":"https://github.com/vitest-dev/vitest/blob/d568f8ce3739b532d5bf2c1ee1e45e8a8a473d09/packages/vitest/src/node/config/resolveConfig.ts#L434-L470","documentation":"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.","triggerScenarios":"Set `coverage: { enabled: true, provider: 'istanbul' }` together with `experimental: { viteModuleRunner: false }`.","commonSituations":"Opting out of the Vite module runner for performance/compat reasons while still wanting Istanbul coverage; copying an experimental flag from a workaround.","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."],"exampleFix":"// before\nexport default defineConfig({ test: { coverage: { enabled: true, provider: 'istanbul' }, experimental: { viteModuleRunner: false } } })\n// after\nexport default defineConfig({ test: { coverage: { enabled: true, provider: 'v8' } } })","handlingStrategy":"type-guard","validationCode":"function assertCoverageCompatible(config: any) {\n  if (config?.coverage?.enabled && config.coverage.provider === 'istanbul' && config.experimental?.viteModuleRunner === false) {\n    throw new Error('Istanbul coverage requires viteModuleRunner; switch to v8 or remove the experimental flag.')\n  }\n}","typeGuard":"function isCoverageConfigValid(config: any): boolean {\n  return !(config?.coverage?.enabled && config.coverage.provider === 'istanbul' && config.experimental?.viteModuleRunner === false)\n}","tryCatchPattern":null,"preventionTips":["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."],"tags":["config","coverage","istanbul","v8","experimental"],"analyzedSha":"d568f8ce3739b532d5bf2c1ee1e45e8a8a473d09","analyzedAt":"2026-08-03T20:23:56.861Z","schemaVersion":2}