vitest-dev/vitest · error · Error
Failed to mock '${url}'. See the cause for more information.
Error message
Failed to mock '${url}'. See the cause for more information. What it means
`NativeModuleMocker.loadManualMock` (`nativeModuleMocker.ts:163`) parses the original module to collect its export names (`collectModuleExports`) and then generates a manual-mock wrapper (`createManualModuleSource`). If either step throws (lexer/parse failure, unusual format), this `Error` wraps the cause. It affects `vi.mock('mod', factory)` — the factory itself isn't run yet; this is the export-shape detection on the real module.
Source
Thrown at packages/vitest/src/runtime/moduleRunner/nativeModuleMocker.ts:163
if (transformedCode == null) {
return
}
const format = result.format?.startsWith('module') ? 'module' : 'commonjs'
try {
// we parse the module with es/cjs-module-lexer to find the original exports -- we assume the same ones are returned from the factory
// injecting new keys is not supported (and should not be advised anyway)
const exports = collectModuleExports(moduleId, transformedCode, format)
const manualMockedModule = createManualModuleSource(moduleId, exports)
return {
format: 'module',
source: manualMockedModule,
shortCircuit: true,
}
}
catch (cause) {
throw new Error(`Failed to mock '${url}'. See the cause for more information.`, { cause })
}
}
private processedModules = new Map<string, number>()
public checkCircularManualMock(url: string): void {
const filename = url.startsWith('file://') ? fileURLToPath(url) : url
const id = cleanUrl(normalizeModuleId(filename))
this.processedModules.set(id, (this.processedModules.get(id) ?? 0) + 1)
// the module is mocked and requested a second time, let's resolve
// the factory function that will redefine the exports later
if (this.originalModulePromises.has(id)) {
const factoryPromise = this.factoryPromises.get(id)
this.originalModulePromises.get(id)?.resolve({ __factoryPromise: factoryPromise })
}
}
private originalModulePromises = new Map<string, DeferPromise<any>>()View on GitHub (pinned to d568f8ce37)
Solutions
- Inspect `error.cause` for the specific lexer/parse failure.
- Verify the real module loads normally first (import it in a non-test file) — if it can't load, fix the source.
- If export collection is fundamentally broken for that module, avoid mocking it via the loader and inject the dependency another way (e.g. dependency injection in the SUT).
Defensive patterns
Strategy: try-catch
Validate before calling
// Verify the real module loads before mocking it.
try {
await import('mod')
} catch {
throw new Error('Cannot mock mod: the real module fails to load')
} Try / catch
try {
vi.mock('mod', factory)
} catch (e) {
if (e instanceof Error && /Failed to mock.*See the cause/.test(e.message)) {
console.error(e.cause)
// fall back to not mocking, or inject the dependency differently
} else throw e
} Prevention
- Confirm the real module imports cleanly before mocking it.
- Inspect error.cause to find the exact lexer/parse failure.
- For modules with unusual export shapes, avoid loader-based mocking.
When it happens
Trigger: `vi.mock('mod', () => ({...}))` where `mod` fails export collection — unparseable source, exotic CJS/ESM shape, or a format the lexer doesn't recognize.
Common situations: Manual mocking a module with unusual export patterns; a CJS module with dynamic exports the lexer misses; an `.mjs`/`.cjs` ambiguity.
Related errors
- Cannot automock '${url}' because it failed to parse.
- Cannot set serialized manual mock. Define a factory function
- [vitest] Manual mocks require a factory function.
- [vitest] vi.mock("${raw}", factory?: () => unknown) is not r
- Mock ${id} wasn't registered. This is probably a Vitest erro
AI-assisted analysis of vitest-dev/vitest@d568f8ce37 (2026-08-03).
Data as JSON: /data/errors/786227e6e0d15d20.json.
Report an issue: GitHub.