{"record":{"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/1fa9837ec26533512fdcad8baebf249771bd340a/packages/mocker/src/browser/mocker.ts#L46-L82","documentation":"Thrown by `ModuleMocker.importActual(id, importer)` in browser mode when `rpc.resolveId(id, importer)` returns null — meaning Vite's resolver could not find the module. `importActual` backs `vi.importActual` / `vi.importMock` in browser mode; a null resolution means the specifier does not resolve to any file from the given importer.","triggerScenarios":"Calling `vi.importActual('./nonexistent')` or `vi.importActual('uninstalled-pkg')` from a test or another module. Also triggered by incorrect alias configuration, case-sensitivity mismatches on case-sensitive filesystems, or a missing file extension when the resolver cannot disambiguate.","commonSituations":"Typos in the module path; deleting a source file but leaving a `vi.importActual` reference; alias mismatches between `vite.config`/`vitest.config`; monorepo package not built or not linked so the specifier resolves to nothing; case-sensitive path issues when developing on macOS/Windows and running CI on Linux.","solutions":["Verify the specifier resolves from the importing file with a plain `import` in a scratch file.","Check `resolve.alias` in your Vitest/Vite config covers the specifier.","In monorepos, build the target package or confirm the workspace symlink exists.","Match the exact casing of the path on disk, especially for CI on Linux."],"exampleFix":"// before — typo / unresolvable specifier\nconst actual = await vi.importActual('./utls')\n// after — correct path\nconst actual = await vi.importActual('./utils')","handlingStrategy":"try-catch","validationCode":"// Validate the specifier resolves before calling importActual.\n// (resolveId via the Vite resolver; in user code, a try-import in a scratch file is the cheapest check.)\ntry {\n  await import.meta.resolve(id, importer)\n} catch {\n  throw new Error(`importActual target does not resolve: ${id} from ${importer}`)\n}","typeGuard":null,"tryCatchPattern":"try {\n  const actual = await vi.importActual('./mod')\n} catch (err) {\n  if (err instanceof Error && err.message.includes('Cannot resolve')) {\n    // log, skip, or provide a fallback stub\n  }\n  throw err\n}","preventionTips":["Keep vi.importActual specifiers in sync with real file paths — refactor tools often miss string literals.","Configure resolve.alias for any non-obvious specifier you import in tests.","In monorepos, ensure workspace packages are built and linked before running browser tests."],"tags":["browser-mode","import-actual","module-resolution","vite-alias"],"backgroundTag":null,"analyzedSha":"1fa9837ec26533512fdcad8baebf249771bd340a","analyzedAt":"2026-08-11T16:11:39.638Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}