{"id":"c48cce2c2810e60b","repo":"vitest-dev/vitest","slug":"failed-to-load-custom-reporter-from-path","errorCode":null,"errorMessage":"Failed to load custom Reporter from ${path}","messagePattern":"Failed to load custom Reporter from (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/vitest/src/node/reporters/utils.ts","lineNumber":18,"sourceCode":"import type { ModuleRunner } from 'vite/module-runner'\nimport type { Vitest } from '../core'\nimport type { ResolvedConfig } from '../types/config'\nimport type { Reporter } from '../types/reporter'\nimport type { BlobReporter } from './blob'\nimport type { BuiltinReporters, DefaultReporter, DotReporter, GithubActionsReporter, HangingProcessReporter, JsonReporter, JUnitReporter, TapReporter } from './index'\nimport { ReportersMap } from './index'\n\nasync function loadCustomReporterModule<C extends Reporter>(\n  path: string,\n  runner: ModuleRunner,\n): Promise<new (options?: unknown) => C> {\n  let customReporterModule: { default: new () => C }\n  try {\n    customReporterModule = await runner.import(path)\n  }\n  catch (customReporterModuleError) {\n    throw new Error(`Failed to load custom Reporter from ${path}`, {\n      cause: customReporterModuleError as Error,\n    })\n  }\n\n  if (\n    customReporterModule.default === null\n    || customReporterModule.default === undefined\n  ) {\n    throw new Error(\n      `Custom reporter loaded from ${path} was not the default export`,\n    )\n  }\n\n  return customReporterModule.default\n}\n\nfunction createReporters(\n  reporterReferences: ResolvedConfig['reporters'],","sourceCodeStart":1,"sourceCodeEnd":36,"githubUrl":"https://github.com/vitest-dev/vitest/blob/d568f8ce3739b532d5bf2c1ee1e45e8a8a473d09/packages/vitest/src/node/reporters/utils.ts#L1-L36","documentation":"Thrown by `loadCustomReporterModule` (utils.ts:18) when `runner.import(path)` rejects while loading a custom reporter module. The original error is attached via `Error({ cause })`. This wraps any module-resolution, syntax, or runtime error that occurs when Vitest tries to import the reporter path, preserving the underlying cause for diagnosis.","triggerScenarios":"Configuring `reporters: [['./my-reporter.ts', {}]]` where the path doesn't exist, has a syntax error, throws on import, or has an unresolvable dependency; referencing an npm package name that isn't installed.","commonSituations":"Typo in the reporter path; missing dependency the reporter imports; ESM/CJS mismatch causing import failure; reporter file outside the project root or not on the module resolution path.","solutions":["Inspect `error.cause` for the real import failure (resolution, syntax, or runtime).","Verify the reporter path is correct and the file exists; use a path resolvable by the Vite module runner.","Install any missing dependencies the reporter imports.","Ensure the reporter file has no syntax errors (`node --check` or run it directly)."],"exampleFix":"// before\nexport default defineConfig({ test: { reporters: [['./reporter/mis-typed.ts', {}]] } })\n// after: fix path / fix syntax in ./reporter/my-reporter.ts","handlingStrategy":"try-catch","validationCode":"import { pathExists } from 'fs-extra'\nif (!await pathExists(reporterPath)) throw new Error(`Reporter path does not exist: ${reporterPath}`)","typeGuard":null,"tryCatchPattern":"try {\n  await import(reporterPath)\n} catch (e) {\n  throw new Error(`Custom reporter ${reporterPath} failed to load`, { cause: e })\n}","preventionTips":["Verify the reporter path exists and is resolvable before adding it to config.","Keep reporter dependencies installed.","Test the reporter module imports cleanly in isolation first."],"tags":["reporter","custom-reporter","import","config"],"analyzedSha":"d568f8ce3739b532d5bf2c1ee1e45e8a8a473d09","analyzedAt":"2026-08-03T20:23:56.861Z","schemaVersion":2}