{"record":{"id":"ab2ee311224bae86","repo":"vitest-dev/vitest","slug":"mock-id-wasn-t-registered-this-is-probably-a-v","errorCode":null,"errorMessage":"Mock ${id} wasn't registered. This is probably a Vitest error. Please, open a new issue with reproduction.","messagePattern":"Mock (.+?) wasn't registered\\. This is probably a Vitest error\\. Please, open a new issue with reproduction\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/mocker/src/browser/mocker.ts","lineNumber":34,"sourceCode":"\n  constructor(\n    private interceptor: ModuleMockerInterceptor,\n    private rpc: ModuleMockerRPC,\n    private createMockInstance: CreateMockInstanceProcedure,\n    private config: ModuleMockerConfig,\n  ) {}\n\n  public async prepare(): Promise<void> {\n    if (!this.queue.size) {\n      return\n    }\n    await Promise.all([...this.queue.values()])\n  }\n\n  public async resolveFactoryModule(id: string): Promise<Record<string | symbol, any>> {\n    const mock = this.registry.get(id)\n    if (!mock || mock.type !== 'manual') {\n      throw new Error(`Mock ${id} wasn't registered. This is probably a Vitest error. Please, open a new issue with reproduction.`)\n    }\n    const result = await mock.resolve()\n    return result\n  }\n\n  public getFactoryModule(id: string): any {\n    const mock = this.registry.get(id)\n    if (!mock || mock.type !== 'manual') {\n      throw new Error(`Mock ${id} wasn't registered. This is probably a Vitest error. Please, open a new issue with reproduction.`)\n    }\n    if (!mock.cache) {\n      throw new Error(`Mock ${id} wasn't resolved. This is probably a Vitest error. Please, open a new issue with reproduction.`)\n    }\n    return mock.cache\n  }\n\n  public async invalidate(): Promise<void> {\n    const ids = Array.from(this.mockedIds)","sourceCodeStart":16,"sourceCodeEnd":52,"githubUrl":"https://github.com/vitest-dev/vitest/blob/1fa9837ec26533512fdcad8baebf249771bd340a/packages/mocker/src/browser/mocker.ts#L16-L52","documentation":"Thrown by `ModuleMocker.resolveFactoryModule(id)` (browser mode) when the registry lookup for `id` returns either nothing or a mock whose `type` is not `'manual'`. This method is called to execute a `vi.mock(path, factory)` factory at import time; reaching it with an unregistered or wrong-typed mock means the hoisting/registration pipeline did not populate the registry as expected. The message explicitly flags it as a likely Vitest internal bug.","triggerScenarios":"The browser-side mocker's `resolveFactoryModule` is invoked for a module id that was never registered via `queueMock` → `registry.register('manual', ...)`, or whose registration resolved to an `automock`/`autospy`/`redirect` type instead. Typical when `prepare()` (which drains the registration queue) has not completed before the dynamic import triggers resolution, or when `invalidate()` cleared the registry mid-test.","commonSituations":"Browser mode tests where `vi.mock` is called conditionally or after the module is already imported; race conditions between `vi.unmock` and a pending import; HMR or test isolation logic that calls `registry.clear()` before all factories resolve.","solutions":["Ensure `vi.mock(path, factory)` calls are at the top level of the test file so they are hoisted and registered before any import.","Avoid calling `vi.unmock` and then importing the same module in the same test without re-registering the mock.","If using a custom test runner, verify it awaits `mocker.prepare()` before importing test modules.","Report a Vitest bug with a browser-mode reproduction if the error persists with top-level `vi.mock`."],"exampleFix":"// before — vi.mock nested inside a test body\nit('works', () => {\n  vi.mock('./mod', () => ({ fn: () => 1 }))\n  require('./mod')\n})\n// after — hoisted to top level\nvi.mock('./mod', () => ({ fn: () => 1 }))\nit('works', () => {\n  require('./mod')\n})","handlingStrategy":"validation","validationCode":"// Before calling resolveFactoryModule, confirm the mock is registered as manual.\nconst mock = mocker.getMockedModuleById(id)\nif (!mock || mock.type !== 'manual') {\n  throw new Error(`Cannot resolve factory for ${id}: not registered as a manual mock`)\n}\nawait mocker.resolveFactoryModule(id)","typeGuard":"import type { ManualMockedModule } from '@vitest/mocker'\nfunction isManualMock(mock: unknown): mock is ManualMockedModule {\n  return typeof mock === 'object' && mock !== null && (mock as any).type === 'manual'\n}","tryCatchPattern":null,"preventionTips":["Always place vi.mock(path, factory) at module top level so registration completes before imports.","Await mocker.prepare() before importing modules that depend on mocks.","Avoid calling vi.unmock for a module whose factory is still pending resolution."],"tags":["browser-mode","mock-registry","vi-mock","race-condition"],"backgroundTag":null,"analyzedSha":"1fa9837ec26533512fdcad8baebf249771bd340a","analyzedAt":"2026-08-11T16:11:39.638Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}