vitest-dev/vitest · error · Error
Runner must export a default function, but got ${typeof mod.
Error message
Runner must export a default function, but got ${typeof mod.default} imported from ${config.runner} What it means
Thrown by getTestRunnerConstructor when a custom runner is configured (`config.runner` points to a module path) but the imported module has no `default` export that is usable as a constructor. Vitest needs `export default class MyRunner ...` (or a function) so it can do `new TestRunner(config)`. The message reports the actual typeof value it received so you can see what shape the module exported.
Source
Thrown at packages/vitest/src/runtime/runners/index.ts:20
import type { SerializedConfig } from '../config'
import type { TestModuleRunner } from '../moduleRunner/testModuleRunner'
import type { VitestRunner, VitestRunnerConstructor } from '../runner/types'
import { takeCoverageInsideWorker } from '../../integrations/coverage'
import { rpc } from '../rpc'
import { loadDiffConfig, loadSnapshotSerializers } from '../setup-common'
import { getWorkerState } from '../utils'
import { TestRunner } from './test'
async function getTestRunnerConstructor(
config: SerializedConfig,
moduleRunner: TestModuleRunner,
): Promise<VitestRunnerConstructor> {
if (!config.runner) {
return TestRunner as any as VitestRunnerConstructor
}
const mod = await moduleRunner.import(config.runner)
if (!mod.default && typeof mod.default !== 'function') {
throw new Error(
`Runner must export a default function, but got ${typeof mod.default} imported from ${
config.runner
}`,
)
}
return mod.default as VitestRunnerConstructor
}
export async function resolveTestRunner(
config: SerializedConfig,
moduleRunner: TestModuleRunner,
traces: Traces,
): Promise<VitestRunner> {
const TestRunner = await getTestRunnerConstructor(config, moduleRunner)
const testRunner = new TestRunner(config)
// inject private executor to every runner
Object.defineProperty(testRunner, 'moduleRunner', {View on GitHub (pinned to d568f8ce37)
Solutions
- Add `export default` to the runner module and make it a class or function: `export default class MyRunner extends VitestRunner { ... }`.
- Verify the path in `config.runner` resolves to the intended file.
- If using TypeScript, make sure the build emits a usable default export.
- Extend the VitestRunner base type from the runtime types so the shape is correct.
Example fix
// before (./my-runner.js)
export class MyRunner { /* ... */ }
// after
import { VitestRunner } from 'vitest/runners'
export default class MyRunner extends VitestRunner {
importFile(file) { /* ... */ }
} Defensive patterns
Strategy: type-guard
Validate before calling
// Verify your runner module before pointing config at it
import * as runnerMod from './my-runner.js'
if (typeof runnerMod.default !== 'function') {
throw new Error('runner module must export a default class/function')
} Type guard
import type { VitestRunnerConstructor } from 'vitest'
function isRunnerCtor(mod: any): mod is { default: VitestRunnerConstructor } {
return mod && typeof mod.default === 'function'
} Prevention
- Always `export default class ... extends VitestRunner`.
- Keep a unit test that imports your runner and asserts typeof default === 'function'.
- Point config.runner at the built output, not a stale source path.
When it happens
Trigger: Setting `test.runner: './my-runner.js'` where that file only has named exports, no default export. Exporting default as an object or a plain value instead of a class/function. Forgetting to add `export default` to the runner file.
Common situations: Writing a custom VitestRunner for the first time and omitting the default export. Refactoring a runner from default to named export. Pointing config.runner at the wrong file that happens to export something else.
Related errors
- Runner must implement "importFile" method.
- invalid diff config file ${config.diff}. Must have a default
- invalid snapshot serializer file ${file}. Must export a defa
- Failed to import custom OpenTelemetry SDK script (${options.
- You've enabled headless mode for "preview" provider but it d
AI-assisted analysis of vitest-dev/vitest@d568f8ce37 (2026-08-03).
Data as JSON: /data/errors/7960cf0a824dcf1c.json.
Report an issue: GitHub.