vitest-dev/vitest · error · Error
Failed to load custom CoverageProviderModule from
Error message
Failed to load custom CoverageProviderModule from ${options.customProviderModule} What it means
When test.coverage.provider is set to a custom value, Vitest loads the module at options.customProviderModule via the loader. If that import rejects (module not found, syntax error, runtime throw at load time), the original error is wrapped and re-thrown with { cause } pointing at the underlying failure and naming the configured module path.
Solutions
- Verify the customProviderModule path resolves and the file/package exists.
- Inspect error.cause (the wrapped error) for the real import failure (ENOENT, syntax error, missing dep).
- Use an absolute path or a resolvable package name for customProviderModule.
- Import the module manually (node -e "import('./my-provider')") to reproduce and fix the load error.
Example fix
// before
coverage: { provider: 'custom', customProviderModule: './cov.js' }
// file is actually ./src/cov.js
// after
coverage: { provider: 'custom', customProviderModule: './src/cov.js' } Defensive patterns
Strategy: try-catch
Validate before calling
import { existsSync } from 'node:fs'
import { resolve } from 'node:path'
function assertProviderPath(p) {
if (!p) throw new Error('customProviderModule not set')
if (p.startsWith('.') && !existsSync(resolve(p))) throw new Error('provider file missing: ' + p)
} Try / catch
try {
await loader.import(customProviderModule)
} catch (e) {
// e.cause has the real ENOENT/syntax error; surface it
throw new Error('cannot load provider: ' + e.cause?.message)
} Prevention
- Use an absolute or package-name path for customProviderModule.
- Import the provider manually first to confirm it loads.
- Check error.cause for the underlying import failure.
When it happens
Trigger: test.coverage.provider='custom' with coverage.customProviderModule pointing at a path/package that cannot be imported — wrong path, missing dependency, file does not exist, or the module throws during evaluation.
Common situations: Typo in customProviderModule path, relative path that does not resolve from the config location, the provider package is not installed, or the provider module throws on import (e.g. imports a missing peer dep).
Related errors
- Custom CoverageProviderModule loaded from
- "Istanbul" coverage provider is not compatible with…
- vitest/browser can be imported only inside the Browser…
- vitest/browser can be imported only inside the Browser…
- @vitest/coverage-v8 does not work with
AI-assisted analysis of vitest-dev/vitest@1fa9837ec2 (2026-08-11).
Data as JSON: /api/errors/124aa4963bd33c17.
Report an issue: GitHub.
Appendix: source
Thrown at packages/vitest/src/utils/coverage.ts:90
? await loader.import(builtInModule)
: await import(/* @vite-ignore */ builtInModule)
if (!coverageModule) {
throw new Error(
`Failed to load ${CoverageProviderMap[provider]}. Default export is missing.`,
)
}
return coverageModule
}
let customProviderModule
try {
customProviderModule = await loader.import(options.customProviderModule!)
}
catch (error) {
throw new Error(
`Failed to load custom CoverageProviderModule from ${options.customProviderModule}`,
{ cause: error },
)
}
if (customProviderModule.default == null) {
throw new Error(
`Custom CoverageProviderModule loaded from ${options.customProviderModule} was not the default export`,
)
}
return customProviderModule.default
}
View on GitHub (pinned to 1fa9837ec2)