Read Vercel logs systematically, categorize errors, and fix locally before re-pushing.
Vercel build failures produce a wall of log output. Knowing where to look, how to categorize the error, and what to fix locally (not in Vercel) is the skill that separates operators from developers who iterate in production.
⬡ What you'll build
Vercel shows build output in order. When a build fails, the error that caused the failure is usually not the last thing shown — it's somewhere in the middle, followed by cascading failures and the final "Build failed" message.
The navigation pattern:
Error:, error TS, Module not found, Type error:The cascade problem: Next.js build errors often show "Failed to compile" followed by 20+ lines of type errors that are all caused by one missing type definition. Fix the root error; the cascade disappears.
Signature:
Type error: Type 'string | undefined' is not assignable to parameter of type 'string'.
Where: A recent change broke a type contract. Either a type was made more strict, a new nullable value wasn't handled, or a function signature changed and call sites weren't updated.
Fix locally:
node node_modules/typescript/bin/tsc --noEmit
# Shows every type error with file and line number
# Fix them all, verify tsc passes, then pushSignature:
Module not found: Can't resolve '@/lib/utils'
Module not found: Can't resolve './components/Button'
Causes:
tsconfig.jsonFix locally:
# Verify the file exists
ls app/components/Button.tsx
# Check tsconfig.json for path alias config
cat tsconfig.json | grep -A5 '"paths"'Signature:
Module not found: Can't resolve 'fs'
Module not found: Can't resolve 'path'
Error: The edge runtime does not support Node.js built-ins
Cause: A server-only module (fs, path, crypto, etc.) is being imported in a client component, Edge Runtime function, or a file that gets bundled for the browser.
The most common source: A utility file that imports fs is also imported by a 'use client' component. The entire import chain pulls fs into the client bundle.
Fix:
# Find what imports the server-only module
grep -r "from 'fs'" --include="*.ts" --include="*.tsx" .
grep -r "import fs" --include="*.ts" --include="*.tsx" .
# Check if those files are imported by client components
grep -r "from '@/lib/your-server-module'" --include="*.tsx" .Before: lib/utils.ts imports fs — imported by client components
After: Split into:
lib/utils.ts ← pure utilities, no fs import, safe for client
lib/utils.server.ts ← server-only utilities with fs, never imported by clientsSignature:
Error occurred prerendering page "/your-route"
Error: Cannot read properties of undefined (reading 'map')
Cause: Code that runs at build time (in generateStaticParams, generateMetadata, or top-level Server Components) fails because data isn't available at build time that you expected to be there.
Fix pattern: Verify data exists before using it. Add null checks. Make generateStaticParams return an empty array if the data source is unavailable:
export async function generateStaticParams() {
try {
const items = await fetchItems()
return items.map(item => ({ slug: item.slug }))
} catch {
return [] // build succeeds with no static pages — they render on demand
}
}Signature:
Module not found: Can't resolve '@/Components/Button'
(Works locally on macOS/Windows, fails on Vercel Linux)
Cause: Your file is components/Button.tsx but you imported it as @/Components/Button. macOS and Windows file systems are case-insensitive and find the file. Vercel's Linux file system is case-sensitive and doesn't.
Find all case mismatches:
# Check imports for capitalization mismatches
grep -r "from '@/Components" --include="*.tsx" --include="*.ts" .
grep -r "from '@/Lib" --include="*.tsx" --include="*.ts" .
grep -r "from '@/App" --include="*.tsx" --include="*.ts" .The rule: Import paths must match the file system exactly, case included. Enforce with ESLint import/no-unresolved if this is a recurring issue.
Never iterate in Vercel. Every failed push costs build minutes and takes 2–4 minutes to get feedback. Local build is free and takes 30–90 seconds. Fix locally, push once.
When Claude helps diagnose a build failure, don't paraphrase the error. Give it the raw log.
Failure Pattern — Paraphrasing the build error
✕ Before (broken pattern)
The build is failing because of some TypeScript problem with the auth types. Can you fix it?
✓ After (production pattern)
Build failure. Full error from Vercel log: Type error: Argument of type 'string | undefined' is not assignable to parameter of type 'string'. → app/api/profile/route.ts:45:30 The session.userId field comes from lib/auth.ts:parseSession(). The function returns SessionData | null — I think that's where the undefined is coming from. Diagnose the root cause. Don't change anything yet.
Lesson: Claude needs the exact error, file, and line number. Paraphrasing loses the signal. Copy the raw log output — don't summarize it.
You can diagnose Vercel failures when: