vitest-dev/vitest · error · Error
Benchmark provider loaded from
Error message
Benchmark provider loaded from "${provider}" did not have a default export. What it means
After successfully importing a custom benchmark provider module, Vitest checks that `mod.default` is not null/undefined. A benchmark provider must be supplied as the module's default export. This fires when the module loads but exposes its provider only via a named export, or has no default at all.
Solutions
- Add `export default { run(group) { ... } }` to the provider module.
- If using CommonJS, ensure `module.exports = { default: { run: ... } }` or rely on the runner's interop by setting `module.exports.default = { run }`.
- Confirm the provider object conforms to `BenchmarkProvider`: `{ run: (group: BenchmarkGroup) => Promise<BenchResult[]> }`.
Example fix
// before - provider.ts
export const myProvider = { async run(group) { return [] } }
// after
export default { async run(group) { return [] } } Defensive patterns
Strategy: type-guard
Validate before calling
const mod = await import(providerPath); if (mod.default == null) throw new Error('add `export default` to provider') Type guard
function hasDefault<T>(m: Record<string, any>): m is { default: T } { return m.default != null } Try / catch
try { provider = await loadProviderModule(path, runner) } catch (e) { if (/default export/.test(e.message)) fixProviderDefault(); else throw e } Prevention
- Always author the provider with `export default { run(group) { ... } }`.
- In a unit test, `assert(mod.default != null)` after importing.
- When using CJS, set `module.exports.default = ...` explicitly.
When it happens
Trigger: Provider module uses `export const provider = { run: ... }` or `export function run(...)` without `export default`. The check at benchmark.ts:113 (`if (mod.default == null)`) triggers after a successful import. Common with CJS-interop where the namespace object's `default` is undefined.
Common situations: Migrating a named-export provider to Vitest and forgetting the default export; provider authored as CommonJS (`module.exports = { run }`) but the interop layer does not synthesize a `default`; provider exports a class but as a named binding.
Related errors
- benchmark provider did not return a result for
- Failed to load benchmark provider from
- All browser instances within a project must use the same…
- `bench.compare()` expects every argument to be the return…
- `bench.compare()` requires at least 2 benchmarks, received
AI-assisted analysis of vitest-dev/vitest@1fa9837ec2 (2026-08-11).
Data as JSON: /api/errors/199f83fe6a4695ab.
Report an issue: GitHub.
Appendix: source
Thrown at packages/vitest/src/runtime/benchmark.ts:117
async function loadProviderModule(
provider: string,
moduleRunner: TestModuleRunner,
): Promise<BenchmarkProvider> {
let mod: Record<string, any>
try {
mod = await moduleRunner.import(provider)
}
catch (error) {
throw new Error(
`Failed to load benchmark provider from "${provider}".`,
{ cause: error },
)
}
if (mod.default == null) {
throw new Error(
`Benchmark provider loaded from "${provider}" did not have a default export.`,
)
}
return mod.default
}
/**
* Resolves the benchmark provider for the current worker, importing a custom
* provider module on first use. The result is cached for the lifetime of the
* worker so a custom provider is imported at most once.
*/
function resolveBenchmarkProvider(
config: SerializedConfig,
moduleRunner: TestModuleRunner,
): Promise<BenchmarkProvider> {
if (!cachedProvider) {
const provider = config.benchmark.provider
cachedProvider = !provider
? Promise.resolve(createDefaultBenchmarkProvider(config))
: loadProviderModule(provider, moduleRunner)
}View on GitHub (pinned to 1fa9837ec2)