{"record":{"id":"49b82d5a3225ab55","repo":"vitest-dev/vitest","slug":"mock-id-wasn-t-resolved-this-is-probably-a-vit","errorCode":null,"errorMessage":"Mock ${id} wasn't resolved. This is probably a Vitest error. Please, open a new issue with reproduction.","messagePattern":"Mock (.+?) wasn't resolved\\. 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":46,"sourceCode":"    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)\n    if (!ids.length) {\n      return\n    }\n    await this.rpc.invalidate(ids)\n    await this.interceptor.invalidate()\n    this.registry.clear()\n  }\n\n  public async importActual<T>(id: string, importer: string): Promise<T> {\n    const resolved = await this.rpc.resolveId(id, importer)\n    if (resolved == null) {\n      throw new Error(","sourceCodeStart":28,"sourceCodeEnd":64,"githubUrl":"https://github.com/vitest-dev/vitest/blob/1fa9837ec26533512fdcad8baebf249771bd340a/packages/mocker/src/browser/mocker.ts#L28-L64","documentation":"Thrown by `getFactoryModule(id)` after the mock is confirmed present and manual-typed, but `mock.cache` is falsy. `ManualMockedModule.cache` is populated only after `resolve()` (which executes the factory) completes successfully. A falsy cache means the factory was never resolved, or an async factory's promise has not settled yet. The message labels this a probable Vitest internal bug because `getFactoryModule` should only be called on already-resolved modules.","triggerScenarios":"`getFactoryModule` is called before `resolveFactoryModule` (or `mock.resolve()`) has completed — e.g., a synchronous code path reads the cache while an async factory is still pending, or `resolve()` threw and cleared `cache` before `getFactoryModule` reads it.","commonSituations":"Browser mode with an async `vi.mock` factory that has not settled when the module is first imported; a factory that throws synchronously, leaving `cache` undefined; test-runner ordering bugs where the cache read races the resolution.","solutions":["Ensure the factory returns synchronously (or that `resolveFactoryModule` is awaited) before any code reads the module.","Check the factory for thrown errors — a throwing factory leaves `cache` undefined.","Report a Vitest bug if the factory is synchronous and top-level but the error still appears."],"exampleFix":"// before — async factory read before settlement\nvi.mock('./mod', async () => ({ fn: await load() }))\n// after — synchronous factory, or await resolution\nvi.mock('./mod', () => ({ fn: vi.fn() }))","handlingStrategy":"validation","validationCode":"// Ensure the factory has resolved (cache populated) before reading it.\nconst mock = mocker.getMockedModuleById(id)\nif (mock && mock.type === 'manual' && !(mock as any).cache) {\n  await mocker.resolveFactoryModule(id) // populate cache first\n}\nconst cached = mocker.getFactoryModule(id)","typeGuard":"function isResolvedManualMock(mock: unknown): mock is { type: 'manual'; cache: Record<string | symbol, any> } {\n  return typeof mock === 'object' && mock !== null\n    && (mock as any).type === 'manual'\n    && Boolean((mock as any).cache)\n}","tryCatchPattern":null,"preventionTips":["Prefer synchronous factories in vi.mock so cache is populated immediately after resolve().","Await resolveFactoryModule before any synchronous getFactoryModule read.","Inspect factories for thrown errors that would leave cache undefined."],"tags":["browser-mode","mock-registry","async","vi-mock"],"backgroundTag":null,"analyzedSha":"1fa9837ec26533512fdcad8baebf249771bd340a","analyzedAt":"2026-08-11T16:11:39.638Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}