vitest-dev/vitest · error · TypeError
[vitest] Cannot register a mock that is already defined. Exp
Error message
[vitest] Cannot register a mock that is already defined. Expected a JSON representation from `MockedModule.toJSON`, instead got "${event.type}". Use "registry.add()" to update a mock instead. What it means
`MockerRegistry.register()` is overloaded to accept either positional args (build a new mock) or a plain serialized JSON object (rehydrate a mock transferred between processes). Passing an already-constructed `MockedModule` class instance is rejected because the registry expects the DTO shape produced by `toJSON()`. Use `registry.add()` to insert a live instance directly.
Source
Thrown at packages/mocker/src/registry.ts:65
): AutospiedModule
public register(
typeOrEvent: MockedModuleType | MockedModuleSerialized,
raw?: string,
id?: string,
url?: string,
factoryOrRedirect?: string | (() => any),
): MockedModule {
const type = typeof typeOrEvent === 'object' ? typeOrEvent.type : typeOrEvent
if (typeof typeOrEvent === 'object') {
const event = typeOrEvent
if (
event instanceof AutomockedModule
|| event instanceof AutospiedModule
|| event instanceof ManualMockedModule
|| event instanceof RedirectedModule
) {
throw new TypeError(
`[vitest] Cannot register a mock that is already defined. `
+ `Expected a JSON representation from \`MockedModule.toJSON\`, instead got "${event.type}". `
+ `Use "registry.add()" to update a mock instead.`,
)
}
if (event.type === 'automock') {
const module = AutomockedModule.fromJSON(event)
this.add(module)
return module
}
else if (event.type === 'autospy') {
const module = AutospiedModule.fromJSON(event)
this.add(module)
return module
}
else if (event.type === 'redirect') {
const module = RedirectedModule.fromJSON(event)
this.add(module)View on GitHub (pinned to d568f8ce37)
Solutions
- Serialize the instance first: `registry.register(mock.toJSON())`.
- Or add the instance directly: `registry.add(mock)` (no validation/clone, just insert).
- If forwarding between processes, always call `.toJSON()` before IPC and reconstruct on the other side.
Example fix
// before registry.register(existingMock) // after registry.register(existingMock.toJSON()) // or, for a live instance on the same process: registry.add(existingMock)
Defensive patterns
Strategy: type-guard
Validate before calling
import {
AutomockedModule, AutospiedModule,
ManualMockedModule, RedirectedModule,
} from '@vitest/mocker/registry'
function isMockInstance(v: unknown) {
return v instanceof AutomockedModule
|| v instanceof AutospiedModule
|| v instanceof ManualMockedModule
|| v instanceof RedirectedModule
}
// route live instances to add(), DTOs to register()
function upsert(registry: any, mock: unknown) {
if (isMockInstance(mock)) registry.add(mock)
else registry.register(mock)
} Type guard
function isSerializedMockDTO(v: unknown): v is { type: string } {
return typeof v === 'object' && v !== null
&& typeof (v as any).type === 'string'
&& !(v instanceof AutomockedModule
|| v instanceof AutospiedModule
|| v instanceof ManualMockedModule
|| v instanceof RedirectedModule)
} Prevention
- Always call `.toJSON()` before forwarding a mock across a process boundary.
- Use `registry.add()` for live instances and `registry.register()` for DTOs — never mix.
- Centralize mock registration in a helper that branches on instance vs DTO.
When it happens
Trigger: Calling `registry.register(existingModule)` where `existingModule` is an instance of `AutomockedModule`/`AutospiedModule`/`ManualMockedModule`/`RedirectedModule` rather than `existingModule.toJSON()`.
Common situations: Worker-thread mock synchronization forwarding live instances; internal tooling that wraps mocks; replaying a captured mock registry without serializing.
Related errors
- Cannot set serialized manual mock. Define a factory function
- Unknown mock type: ${(event as any).type}
- [vitest] Mocks require a raw string.
- [vitest] Mocks require a url string.
- [vitest] Mocks require an id string.
AI-assisted analysis of vitest-dev/vitest@d568f8ce37 (2026-08-03).
Data as JSON: /data/errors/aa5c8dbf1cf053ac.json.
Report an issue: GitHub.