vitest-dev/vitest · error · Error
Custom reporter loaded from ${path} was not the default expo
Error message
Custom reporter loaded from ${path} was not the default export What it means
Thrown by `loadCustomReporterModule` (utils.ts:27) when the custom reporter module imports successfully but has no `default` export (`customReporterModule.default` is null/undefined). Vitest requires the reporter constructor to be the default export so it can do `new CustomReporter(options)`; a named-only export or a side-effect-only module is rejected.
Source
Thrown at packages/vitest/src/node/reporters/utils.ts:27
async function loadCustomReporterModule<C extends Reporter>(
path: string,
runner: ModuleRunner,
): Promise<new (options?: unknown) => C> {
let customReporterModule: { default: new () => C }
try {
customReporterModule = await runner.import(path)
}
catch (customReporterModuleError) {
throw new Error(`Failed to load custom Reporter from ${path}`, {
cause: customReporterModuleError as Error,
})
}
if (
customReporterModule.default === null
|| customReporterModule.default === undefined
) {
throw new Error(
`Custom reporter loaded from ${path} was not the default export`,
)
}
return customReporterModule.default
}
function createReporters(
reporterReferences: ResolvedConfig['reporters'],
ctx: Vitest,
): Promise<Array<Reporter | DefaultReporter | BlobReporter | DotReporter | JsonReporter | TapReporter | JUnitReporter | HangingProcessReporter | GithubActionsReporter>> {
const runner = ctx.runner
const promisedReporters = reporterReferences.map(
async (referenceOrInstance) => {
if (Array.isArray(referenceOrInstance)) {
const [reporterName, reporterOptions] = referenceOrInstance
if (reporterName === 'html') {View on GitHub (pinned to d568f8ce37)
Solutions
- Add `export default` to the reporter class/function in the module.
- Confirm the configured path points to the file that actually has the default export.
- If loading from a package, check the package's entry exports a default.
Example fix
// before
export class MyReporter implements Reporter { /* ... */ }
// after
export default class MyReporter implements Reporter { /* ... */ } Defensive patterns
Strategy: validation
Validate before calling
const mod = await import(reporterPath)
if (mod.default == null || typeof mod.default !== 'function') {
throw new Error(`${reporterPath} must have a default export constructor`)
} Type guard
const hasDefaultReporter = (m: Record<string, unknown>): m is { default: new (o?: unknown) => any } =>
typeof m.default === 'function' Prevention
- Always author custom reporters with `export default class`.
- Lint/CI-check that reporter modules have a default export.
- Point the config at the file containing the default export.
When it happens
Trigger: Writing a reporter with only a named export (e.g. `export class MyReporter`) and no `export default`; a reporter module whose default export was tree-shaken or is conditionally undefined; importing a utility module instead of the reporter module.
Common situations: Forgetting the `default` keyword when authoring a custom reporter; refactoring that moved the class to a named export; pointing at the wrong entry file of a multi-file reporter package.
Related errors
- Failed to load custom Reporter from ${path}
- Blob reporter is not supported in watch mode
- The vcsProvider module '${vcsProvider}' doesn't have a defau
- Benchmark provider loaded from "${provider}" did not have a
- Custom CoverageProviderModule loaded from ${options.customPr
AI-assisted analysis of vitest-dev/vitest@d568f8ce37 (2026-08-03).
Data as JSON: /data/errors/8bfec209d43e12de.json.
Report an issue: GitHub.