vitest-dev/vitest · error · Error
[vitest] Cannot resolve
Error message
[vitest] Cannot resolve "${id}" imported from "${importer}" What it means
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.
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.
Example fix
// before — typo / unresolvable specifier
const actual = await vi.importActual('./utls')
// after — correct path
const actual = await vi.importActual('./utils') Defensive patterns
Strategy: try-catch
Validate before calling
// Validate the specifier resolves before calling importActual.
// (resolveId via the Vite resolver; in user code, a try-import in a scratch file is the cheapest check.)
try {
await import.meta.resolve(id, importer)
} catch {
throw new Error(`importActual target does not resolve: ${id} from ${importer}`)
} Try / catch
try {
const actual = await vi.importActual('./mod')
} catch (err) {
if (err instanceof Error && err.message.includes('Cannot resolve')) {
// log, skip, or provide a fallback stub
}
throw err
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- automocking files with `export *` is not supported because…
- Failed to import test file
- Mock wasn't registered. This is probably a Vitest error…
- Mock wasn't resolved. This is probably a Vitest error…
- Unknown mock type
AI-assisted analysis of vitest-dev/vitest@1fa9837ec2 (2026-08-11).
Data as JSON: /api/errors/13f8af0d991e6e85.
Report an issue: GitHub.
Appendix: source
Thrown at packages/mocker/src/browser/mocker.ts:64
throw new Error(`Mock ${id} wasn't resolved. This is probably a Vitest error. Please, open a new issue with reproduction.`)
}
return mock.cache
}
public async invalidate(): Promise<void> {
const ids = Array.from(this.mockedIds)
if (!ids.length) {
return
}
await this.rpc.invalidate(ids)
await this.interceptor.invalidate()
this.registry.clear()
}
public async importActual<T>(id: string, importer: string): Promise<T> {
const resolved = await this.rpc.resolveId(id, importer)
if (resolved == null) {
throw new Error(
`[vitest] Cannot resolve "${id}" imported from "${importer}"`,
)
}
const ext = extname(resolved.id)
const url = new URL(resolved.url, this.getBaseUrl())
const query = `_vitest_original&ext${ext}`
const actualUrl = `${url.pathname}${
url.search ? `${url.search}&${query}` : `?${query}`
}${url.hash}`
return this.wrapDynamicImport(() => import(/* @vite-ignore */ actualUrl)).then((mod) => {
if (!resolved.optimized || typeof mod.default === 'undefined') {
return mod
}
// vite injects this helper for optimized modules, so we try to follow the same behavior
const m = mod.default
return m?.__esModule ? m : { ...((typeof m === 'object' && !Array.isArray(m)) || typeof m === 'function' ? m : {}), default: m }
})
}View on GitHub (pinned to 1fa9837ec2)