Fix "Module not found: Can't resolve" on Vercel (works locally)
Updated · Applies to: Vercel, Netlify, Cloudflare Pages, Next.js, Vite, Cursor, v0, Bolt
TL;DR fix: Your import's casing doesn't match the real filename (for example ./components/runTable vs RunTable.tsx). macOS and Windows ignore case, but Vercel builds on case-sensitive Linux. Make the import match the filename exactly. If you renamed the file only by case, git may not have recorded it, so rename it with git mv through a temporary name and push.
Steps
- Copy the exact path from the build log. The Vercel build log shows the path it couldn't resolve, e.g. Module not found: Can't resolve './components/usercard'.
- Compare it with what git actually has. Run git ls-files | grep -i usercard. Vercel only sees what git tracks, with the casing git tracks.
- Fix the import or rename the file. Either change the import to match the file exactly, or rename the file through git: git mv File.tsx file.tmp.tsx then git mv file.tmp.tsx file.tsx.
- Check the other usual suspects. If the casing matches: the file may be in .gitignore or .vercelignore, generated by a local-only script, or behind a path alias (@/) that isn't configured for the build.
- Reproduce the Linux build locally. Run a clean build in a case-sensitive environment (Linux, WSL, a container, or CI) before pushing.
Find every casing mismatch at once
# What git (and therefore Vercel) actually has
git ls-files | grep -i "usercard"
# Rename through a temporary name so git records a case-only change
git mv components/userCard.tsx components/UserCard.tmp.tsx
git mv components/UserCard.tmp.tsx components/UserCard.tsx
git commit -m "Fix filename casing for Linux builds"
git push
Vercel’s knowledge base says the error “almost always comes down to one thing: the casing in your import statement doesn’t exactly match the casing of the actual filename.”
Prompt for your AI tool
Vercel build fails: Module not found: Can't resolve '<path>'. Vercel builds on case-sensitive Linux.
Compare every import path against `git ls-files` exactly (including folder names), fix mismatched
casing in imports, and tell me which files need a `git mv` case rename. Don't create duplicate files. When to get help
Get help if the build fails with many different errors at once, if it only fails in CI and you can't reproduce it, or if your AI tool keeps "fixing" it by creating duplicate files with different casing.
Want us to look at your app?
VibeCPR Rescue Reports are launching soon: we scan your repo and live app, and a human verifies every critical finding. Join the waitlist for early access and founder pricing. You'll also get Patch Notes, our weekly fixes newsletter.
FAQ
Why does my app build locally but fail on Vercel with Module not found?
Usually because of filename casing. Windows and macOS filesystems are case-insensitive by default, so Header.tsx and header.tsx are the same file locally. Vercel builds on case-sensitive Linux, where they are different paths, so an import with the wrong casing fails. Make the import match the filename exactly.
I renamed the file but Vercel still fails. Why?
On a case-insensitive disk, git often doesn't record a case-only rename, so the old name is what gets pushed. Rename through git with a temporary name (git mv Header.tsx header.tmp.tsx, then git mv header.tmp.tsx header.tsx), commit and push. Check with git ls-files.
Could it be something other than casing?
Yes. The file may be excluded by .gitignore or .vercelignore, never committed, generated by a script that only runs locally, or imported through a path alias that the build doesn't resolve. git ls-files shows exactly what Vercel receives.
Sources
Related fixes
- Fix "Your Cloud Firestore database has insecure rules" (Firebase email)
- Fix Stripe webhook "No signatures found matching the expected signature for payload"
- Fix Supabase Edge Function "blocked by CORS policy" (preflight)
- Fix "new row violates row-level security policy for table" (Supabase)
- Fix "404: NOT_FOUND" on refresh in a React/Vite app on Vercel