Vitest "Failed to resolve import" - Fix Module Resolution in CI
Vite (under Vitest) could not resolve an import. The package is missing, an alias is not configured in the Vite/Vitest config, or the path case does not match the real file on a case-sensitive Linux runner.
What this error means
A test file fails to load with "Failed to resolve import '@/lib/db' from 'src/x.test.ts'. Does the file exist?" It often passes on macOS but fails on Linux CI, or after a dependency was dropped.
Error: Failed to resolve import "@/lib/db" from "src/users.test.ts".
Does the file exist?
Plugin: vite:import-analysisCommon causes
Alias not configured for Vitest
A @/... alias defined for the app build is not present in the Vite/Vitest resolve.alias, so the import is unresolvable during tests.
Missing dependency or wrong path case
The package was never installed (or pruned by --omit=dev), or the import case does not match the real filename on a case-sensitive filesystem.
How to fix it
Configure the alias in Vitest
Add resolve.alias (or reuse the Vite config) so Vitest resolves aliases like the build does.
// vitest.config.ts
import { defineConfig } from 'vitest/config';
import { fileURLToPath } from 'node:url';
export default defineConfig({
resolve: { alias: { '@': fileURLToPath(new URL('./src', import.meta.url)) } },
});Fix the path case and install deps
- Match the import path to the real filename exactly, including case.
- Run
npm ciso test-only dependencies are present. - Reuse the app's Vite config in Vitest to keep aliases in sync.
How to prevent it
- Share one Vite config between the app and Vitest.
- Lint imports and develop on a case-sensitive filesystem.
- Commit the lockfile so installs are reproducible.