{"id":"13f8af0d991e6e85","repo":"vitest-dev/vitest","slug":"vitest-cannot-resolve-id-imported-from-i","errorCode":null,"errorMessage":"[vitest] Cannot resolve \"${id}\" imported from \"${importer}\"","messagePattern":"\\[vitest\\] Cannot resolve \"(.+?)\" imported from \"(.+?)\"","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/mocker/src/browser/mocker.ts","lineNumber":64,"sourceCode":"      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(\n        `[vitest] Cannot resolve \"${id}\" imported from \"${importer}\"`,\n      )\n    }\n    const ext = extname(resolved.id)\n    const url = new URL(resolved.url, this.getBaseUrl())\n    const query = `_vitest_original&ext${ext}`\n    const actualUrl = `${url.pathname}${\n      url.search ? `${url.search}&${query}` : `?${query}`\n    }${url.hash}`\n    return this.wrapDynamicImport(() => import(/* @vite-ignore */ actualUrl)).then((mod) => {\n      if (!resolved.optimized || typeof mod.default === 'undefined') {\n        return mod\n      }\n      // vite injects this helper for optimized modules, so we try to follow the same behavior\n      const m = mod.default\n      return m?.__esModule ? m : { ...((typeof m === 'object' && !Array.isArray(m)) || typeof m === 'function' ? m : {}), default: m }\n    })\n  }","sourceCodeStart":46,"sourceCodeEnd":82,"githubUrl":"https://github.com/vitest-dev/vitest/blob/d568f8ce3739b532d5bf2c1ee1e45e8a8a473d09/packages/mocker/src/browser/mocker.ts#L46-L82","documentation":"Thrown by importActual at packages/mocker/src/browser/mocker.ts:62-66 when this.rpc.resolveId(id, importer) returns null. resolveId delegates to Vite's resolver on the server; null means no plugin could resolve the specifier relative to the importer. This surfaces when vi.importActual or a vi.mock factory's importActual helper targets a module Vite cannot find.","triggerScenarios":"Calling vi.importActual('./missing') or vi.importActual('uninstalled-pkg') from a test or mock factory; passing a specifier that is not resolvable from the importer file's location.","commonSituations":"Typo in the module path; the dependency is not installed; the path is correct only relative to a different importer; alias configured in vite.config but not applied to the resolve path used.","solutions":["Verify the specifier resolves from the importer file (check with a normal import in the same file).","Install any missing dependency.","Correct typos or use the alias as configured in vite.config.ts.","If importing a virtual module, ensure the plugin providing it is loaded in the Vitest config."],"exampleFix":"// before\nvi.mock('./db', async () => {\n  return { ...(await vi.importActual('./database')) }\n})\n\n// after\nvi.mock('./db', async () => {\n  return { ...(await vi.importActual<typeof import('./db')>('./db')) }\n})","handlingStrategy":"validation","validationCode":"// Validate the specifier resolves before relying on importActual.\nimport { createRequire } from 'node:module'\nconst require = createRequire(import.meta.url)\nfunction resolvesFromImporter(spec: string, importer: string): boolean {\n  try { require.resolve(spec, { paths: [importer] }); return true } catch { return false }\n}\n\nif (!resolvesFromImporter('./missing', __dirname)) {\n  throw new Error(`importActual target does not resolve: ./missing`)\n}","typeGuard":null,"tryCatchPattern":"try {\n  const actual = await vi.importActual<typeof import('./db')>('./db')\n} catch (e) {\n  if (e instanceof Error && /Cannot resolve/.test(e.message)) {\n    console.error('vi.importActual could not resolve the module; check path/alias/deps.')\n  }\n  throw e\n}","preventionTips":["Confirm the specifier resolves via a normal import in the same file first.","Keep vite.config aliases consistent with how specifiers are written in tests.","Install all dependencies referenced by importActual targets."],"tags":["resolution","import-actual","vite-resolve","module-path"],"analyzedSha":"d568f8ce3739b532d5bf2c1ee1e45e8a8a473d09","analyzedAt":"2026-08-03T20:23:56.861Z","schemaVersion":2}