Build errors
Status: đ© COMPLETE Last updated: 2026-06-21 Plain-English tagline: âIt worked yesterday, why wonât it build now?â The Next.js / TypeScript / Vercel build errors that actually come up, and their fixes.
What this is
A paste-and-find reference for build-time errors. Pattern: error message â what it means â fix.
Most of these come from npm run build (locally) or Vercelâs CI (after git push). The ones marked Vercel-only show up in deploy logs but not in next dev.
âModule not found: Canât resolve ââŠââ
What it means: An import statement points at a path that doesnât exist (from the bundlerâs perspective).
Most common causes:
-
Case sensitivity. You wrote
import X from "./button"but the file isButton.tsx. Windows/macOS donât care; Linux (and Vercel) do.- Fix: Match the case exactly. Renaming on a case-insensitive filesystem may need
git mv -f Button.tsx button.tsx.
- Fix: Match the case exactly. Renaming on a case-insensitive filesystem may need
-
Wrong relative path.
../components/Xwhen it should be../../components/X.- Fix: Use the
@/alias if yourtsconfig.jsonhas one configured.@/components/Xworks from anywhere.
- Fix: Use the
-
Missing npm install. A teammate added a dep; you pulled but didnât re-install.
- Fix:
npm install. If still broken: nukenode_modulesand re-install.
- Fix:
-
TypeScript path alias not configured. You wrote
import X from "@/lib/X"buttsconfig.jsondoesnât define@/*.- Fix: Add
"paths": { "@/*": ["./*"] }undercompilerOptions.
- Fix: Add
-
File extension missing or wrong in modern ESM. Some configs require
.jsextensions in imports.- Fix: Add the extension, or set
"moduleResolution": "bundler"intsconfig.json.
- Fix: Add the extension, or set
Reference: Files and folders â case sensitivity, TypeScript
âType error: âŠâ
What it means: TypeScript caught a type mismatch. npm run dev may have skipped this; npm run build wonât.
Common patterns:
- âProperty âXâ does not exist on type âYââ â youâre accessing a property TypeScript doesnât think is there. Either fix the type or use optional chaining (
obj?.X). - âArgument of type âXâ is not assignable to parameter of type âYââ â you passed the wrong type to a function. Either narrow the value (
if (typeof x === "string")) or fix the call site. - âObject is possibly âundefinedââ â strict mode forbids using a possibly-undefined value. Add a guard:
if (x) { ... }orx?.foo. - âType âX | undefinedâ is not assignable to type âXââ â same idea; you didnât narrow.
Fix: Read the message. It says exactly whatâs wrong. Donât reach for as Y (type assertion) until youâve considered narrowing â assertions silence the compiler but the runtime can still crash.
Last resort: // @ts-expect-error <reason> on the offending line. Better than // @ts-ignore because it errors if the next line was actually fine.
Reference: TypeScript
âHydration failedâ / âText content does not matchâ
What it means: React rendered HTML on the server, then on the client, and the two didnât match.
Common causes:
- Time-dependent code â
new Date().toString(),Date.now(). Server and client get different timestamps. Math.random()in render.- Browser-only APIs â
window,localStorage,documentâ used during render. Server has none of these. - Conditional rendering on
typeof windowâ server returns one thing, client another.
Fix:
- Move the offending code into
useEffect(runs only on client). - Or use a Client Component (
"use client"at top of file). - For UI that genuinely must differ between server and client: render a placeholder during SSR, replace it after mount.
Reference: Next.js gotchas, The DOM â hydration
ââXâ is defined but never usedâ
What it means: ESLint flagged an unused import or variable. By default itâs a warning, but some configs make it a build-failing error.
Fix:
- Just delete the unused thing. Simplest path.
- Prefix with
_to mark intentional:function foo(_unused: string). - Disable for one line:
// eslint-disable-next-line @typescript-eslint/no-unused-vars.
Donât disable the rule project-wide just to ship â the warning exists for a reason.
Reference: Linting
âReferenceError: window is not definedâ (Vercel-only)
What it means: Your code referenced window (or localStorage, document) during server-side execution. Vercelâs serverless runtime doesnât have these.
Fix:
if (typeof window !== "undefined") {
// browser-only code here
}Or move the code into useEffect (Client Components only).
Reference: Client vs server
âError: Failed to fetch dynamically imported moduleâ
What it means: A code-split chunk couldnât load. Usually after a deploy when the userâs tab is on the old code but the chunks have been replaced.
Fix:
- In production: ask the user to refresh.
- To prevent: Next.js + Vercel handle this automatically for most cases via service-worker style chunk versioning. If it persists, check your build output cache settings.
This isnât usually your codeâs fault â itâs a deploy-timing artifact.
âBuild succeeded locally but failed on Vercelâ
What it means: Your local environment is more permissive than Vercelâs.
Most common causes (in order):
- Case sensitivity. Local OS doesnât care; Linux does. See âModule not foundâ above.
- Missing env var. Vercel doesnât have the value local-only
.env.localdefines.- Fix: Vercel dashboard â Settings â Environment Variables â add the var â redeploy.
- TypeScript strict mode mismatch. Different tsconfig in CI, or a type that was inferred locally but errored in CI.
- Different Node version. Specify in
package.json:"engines": { "node": "20.x" }. - DevDependency used in production code.
npm install --omit=devskips dev deps. Move the dep intodependencies.
Reference: How-to: Debug a Vercel build failure, Vercel â common gotchas
âCannot read properties of undefined (reading âXâ)â
What it means: You tried to access .X on something thatâs undefined. Classic JS error.
Fix:
- Optional chaining:
obj?.Xreturnsundefinedinstead of crashing. - Nullish coalescing:
obj?.X ?? "default". - Guard the access:
if (obj) { obj.X }.
Find the cause: if the value should never be undefined, work backwards to where it could have been omitted. Often a missing prop, a forgotten await, or an API response that didnât include the field.
âMaximum call stack size exceededâ
What it means: Infinite recursion. A function calls itself (directly or via a chain) without a base case.
Common cause: an event handler that fires the same event again. setState inside the render body (without a condition). Effects that update the state they depend on without a guard.
Fix: find the loop and add the base case. The error stack usually shows the same few function names repeating â thatâs your loop.
Reference: Recursion
âENOENT: no such file or directoryâ
What it means: Node tried to open a file that doesnât exist.
Common causes:
- Wrong path passed to
fs.readFileor similar. - Working directory isnât what you assumed. Use absolute paths:
import.meta.url(modern),__dirname(CommonJS), orpath.join(process.cwd(), ...). - File was generated at build time but isnât included in deploy. Vercel only ships files that are imported or in
public/.
âEADDRINUSE: address already in use :::3000â
What it means: Another process is using port 3000.
Fix:
# Windows PowerShell
Get-NetTCPConnection -LocalPort 3000 | Select-Object OwningProcess
Stop-Process -Id <pid># macOS / Linux
lsof -i :3000
kill <pid>Or just use a different port: next dev -p 3001.
âCannot find module âXâ or its corresponding type declarationsâ
What it means: You imported a package, but TypeScript canât find the types.
Fix:
- Install types:
npm install -D @types/X. - Modern packages ship types built-in â if
@types/Xdoesnât exist, the package may already have types. Checkpackage.jsonâ"types"or"typings". - Custom modules without types: create
X.d.tswithdeclare module "X";. Quick-and-dirty, but works.
Reference: TypeScript â type definitions for libraries
âOut of memoryâ during build
What it means: Nodeâs default memory limit (~2 GB on Windows, ~4 GB elsewhere) wasnât enough.
Fix:
# Set higher memory limit for build
NODE_OPTIONS="--max-old-space-size=8192" npm run build
# Windows PowerShell
$env:NODE_OPTIONS="--max-old-space-size=8192"
npm run buildIf this happens locally but not on Vercel, your code is probably fine â Vercel build runners have more RAM by default. If it happens on Vercel, you may need a Pro plan or to split your build.
See also
- Common errors â index đ©
- Git errors đ©
- Next.js â common gotchas đ© đŠ
- TypeScript â common gotchas đ©
- Vercel â common gotchas đ© đŠ
- How-to: Debug a Vercel build failure đ©
- npm cheat sheet đ© â the ânuclear resetâ workflow