---
# === IDENTITY ===
id: software/debugging/nextjs-build-failures/2026
canonical_question: "How do I diagnose Next.js build failures?"
aliases:
  - "Next.js build error"
  - "next build fails"
  - "Next.js production build failure"
  - "Next.js Module not found build"
  - "Next.js TypeScript build error"
  - "Next.js heap out of memory build"
  - "Next.js deploy build fails"
  - "Next.js Turbopack build error"
  - "Next.js 16 build failure"
entity_type: software_reference
domain: software > debugging > nextjs_build_failures
region: global
jurisdiction: global
temporal_scope: 2022-2026

# === VERIFICATION ===
last_verified: 2026-05-17
confidence: 0.93
version: 2.1
first_published: 2026-02-17

# === TEMPORAL VALIDITY ===
temporal_validity:
  status: stable
  last_breaking_change: "Next.js 16 (2025-10) — Turbopack default for dev + build; webpack-config-with-no-turbopack-config now errors at build time"
  next_review: 2026-11-13
  change_sensitivity: medium

# === CONSTRAINTS ===
constraints:
  - "Node.js >= 18.18.0 required for Next.js 15+; Node.js >= 20.x recommended for Next.js 16"
  - "Next.js 16 uses Turbopack by default — custom webpack configs require --webpack flag or will be silently ignored"
  - "Never set both typescript.ignoreBuildErrors and eslint.ignoreDuringBuilds in production — hides real bugs"
  - "React 19 removed ReactDOM.render() — all Next.js 15+ projects must use createRoot()"
  - "Turbopack does not support all webpack loaders — check next.config.js turbopack.rules for alternatives"
  - "Environment variables without NEXT_PUBLIC_ prefix are server-only — using them in client code causes undefined at build time"

# === SKIP CONDITIONS ===
skip_this_unit_if:
  - condition: "App runs but renders incorrectly (hydration mismatch warning, not build error)"
    use_instead: "software/debugging/react-hydration-mismatch/2026"
  - condition: "Build succeeds but app shows white screen or runtime crash"
    use_instead: "software/debugging/react-white-screen/2026"
  - condition: "Webpack or Vite build fails (not Next.js specific)"
    use_instead: "software/debugging/webpack-vite-build-failures/2026"

# === AGENT HINTS ===
inputs_needed:
  - key: nextjs_version
    question: "Which Next.js version are you using?"
    type: choice
    options: ["Next.js 16 (Turbopack default)", "Next.js 15", "Next.js 14", "Next.js 13 or older"]
  - key: router_type
    question: "Are you using the App Router (app/) or Pages Router (pages/)?"
    type: choice
    options: ["App Router", "Pages Router", "Both"]
  - key: error_signature
    question: "What is the first error line in the build output?"
    type: text

# === DISTRIBUTION ===
canonical_source: "https://knowledgelib.io/software/debugging/nextjs-build-failures/2026"
suggested_citation: "Source: knowledgelib.io — AI Knowledge Library (verified 2026-05-17)"

# === RELATED UNITS ===
related_kos:
  related_to:
    - id: "software/debugging/webpack-vite-build-failures/2026"
      label: "Webpack and Vite Build Failures"
    - id: "software/migrations/cra-to-nextjs/2026"
      label: "Create React App to Next.js Migration"
  often_confused_with:
    - id: "software/debugging/react-hydration-mismatch/2026"
      label: "React Hydration Mismatch"
    - id: "software/debugging/react-white-screen/2026"
      label: "React White Screen of Death"
  solves:
    - id: "software/debugging/react-too-many-rerenders/2026"
      label: "React Too Many Re-Renders"

# === SOURCES (5-8 authoritative sources) ===
sources:
  - id: src1
    title: "Next.js — Error Messages Reference"
    author: Vercel
    url: https://nextjs.org/docs/messages
    type: official_docs
    published: 2025-12-01
    reliability: authoritative
  - id: src2
    title: "Next.js — next.config.js Options"
    author: Vercel
    url: https://nextjs.org/docs/app/api-reference/next-config-js
    type: official_docs
    published: 2025-12-01
    reliability: authoritative
  - id: src3
    title: "Next.js — Upgrading to Version 16"
    author: Vercel
    url: https://nextjs.org/docs/app/guides/upgrading/version-16
    type: official_docs
    published: 2025-10-21
    reliability: authoritative
  - id: src4
    title: "Next.js — Upgrading to Version 15"
    author: Vercel
    url: https://nextjs.org/docs/app/guides/upgrading/version-15
    type: official_docs
    published: 2024-10-01
    reliability: authoritative
  - id: src5
    title: "Next.js — TypeScript Configuration"
    author: Vercel
    url: https://nextjs.org/docs/app/building-your-application/configuring/typescript
    type: official_docs
    published: 2025-12-01
    reliability: authoritative
  - id: src6
    title: "Sentry — Common Next.js Build Errors"
    author: Sentry
    url: https://sentry.io/answers/next-js-build-errors/
    type: community_resource
    published: 2025-06-01
    reliability: high
  - id: src7
    title: "Next.js — Turbopack API Reference"
    author: Vercel
    url: https://nextjs.org/docs/app/api-reference/turbopack
    type: official_docs
    published: 2025-10-01
    reliability: authoritative
  - id: src8
    title: "Node.js — Diagnostics: Heap Out of Memory"
    author: Node.js Foundation
    url: https://nodejs.org/en/docs/guides/diagnostics/memory
    type: official_docs
    published: 2025-06-01
    reliability: authoritative
  - id: src9
    title: "Next.js 16 Update — What's Breaking and How to Fix It"
    author: Dharmsy
    url: https://www.dharmsy.com/blog/nextjs-16-update-common-issues-and-fixes
    type: technical_blog
    published: 2026-01-12
    reliability: high
---

# How to Diagnose Next.js Build Failures

## TL;DR

- **Bottom line**: Next.js build failures (`next build`) fall into 6 main categories: (1) TypeScript/ESLint errors treated as fatal, (2) module resolution failures (`Module not found`), (3) server/client boundary violations (using `window` in Server Components), (4) data fetching errors in `getStaticProps`/`getStaticPaths`/`generateStaticParams`, (5) out-of-memory crashes on large apps, (6) Turbopack compatibility issues (Next.js 16+ default bundler).
- **Key tool/command**: `npx next build --debug` for verbose output + `NEXT_DEBUG_LOGGING=1` environment variable for detailed build traces. Use `npx next build --webpack` to fall back from Turbopack.
- **Watch out for**: Code that works in `next dev` but fails in `next build` — dev mode is lenient, production build is strict. Next.js 16 uses Turbopack for both dev and build by default, and as of late 2025 patch releases it now errors at build time with `This build is using Turbopack, with a webpack config and no turbopack config` if any custom webpack config is present — no longer silently ignored. Pass `--webpack` to opt out, or migrate to `turbopack.rules` / add an empty `turbopack: {}` block. [src3, src9]
- **Works with**: Next.js 13-16, React 18/19, Node.js 18.18+. Next.js 16 requires Turbopack awareness.

## Constraints
<!-- Agents: read this section before recommending any action from this unit.
     These are hard constraints that must not be violated. -->

- Node.js >= 18.18.0 is required for Next.js 15+; >= 20.x is recommended for Next.js 16. Older Node.js versions cause cryptic build failures. [src4]
- Next.js 16 uses Turbopack by default for `next build`. Custom webpack configurations in `next.config.js` are ignored unless you explicitly pass `--webpack`. Check `turbopack.rules` for loader replacements. [src3, src7]
- Never set both `typescript: { ignoreBuildErrors: true }` and `eslint: { ignoreDuringBuilds: true }` in production — this hides real bugs and accumulates tech debt silently. [src5]
- React 19 (shipped with Next.js 15) removed `ReactDOM.render()`. All projects must use `createRoot()`. Failing to migrate causes build-time errors. [src4]
- Environment variables without the `NEXT_PUBLIC_` prefix are server-only. Using them in client components causes `undefined` at build time, crashing pre-rendering. [src1, src2]
- Next.js 15+ changed `params` and `searchParams` to return Promises in dynamic routes. Using them synchronously causes type errors that block the build. [src4]

## Quick Reference

| # | Error Category | Signature | Likelihood | Fix |
|---|---|---|---|---|
| 1 | TypeScript type errors | `Type error: ... is not assignable to type` | ~22% of cases | Fix types or set `typescript: { ignoreBuildErrors: true }` in `next.config.js` (not recommended) [src5] |
| 2 | Module not found | `Module not found: Can't resolve '...'` | ~18% of cases | Install missing package, fix import path, check case sensitivity on Linux [src1, src6] |
| 3 | Async params type error (Next.js 15+) | `Type 'Promise<any>' is not assignable` | ~12% of cases | Await `params` and `searchParams` in dynamic routes — they return Promises now [src4] |
| 4 | Server/client boundary | `document is not defined`, `window is not defined` | ~10% of cases | Add `"use client"` directive, or move code to `useEffect` [src1, src6] |
| 5 | ESLint errors | `ESLint: ... (error)` blocking build | ~8% of cases | Fix lint errors or set `eslint: { ignoreDuringBuilds: true }` [src2] |
| 6 | Static generation failure | `Error occurred prerendering page "/"` | ~8% of cases | Fix data fetching in `getStaticProps`/`generateStaticParams`, check API availability at build time [src1, src6] |
| 7 | Turbopack webpack config ignored | Build succeeds but missing loaders/transforms | ~6% of cases | Migrate webpack config to `turbopack.rules` or use `--webpack` flag [src3, src7] |
| 8 | Missing `getStaticPaths` | `getStaticPaths is required for dynamic SSG pages` | ~4% of cases | Add `getStaticPaths` or switch to `getServerSideProps` / `force-dynamic` [src1] |
| 9 | Image optimization | `Invalid src prop ... hostname not configured` | ~4% of cases | Add hostname to `images.remotePatterns` in `next.config.js` [src2] |
| 10 | Heap out of memory | `FATAL ERROR: Reached heap limit Allocation failed` | ~3% of cases | Increase memory: `NODE_OPTIONS='--max-old-space-size=4096'` [src8] |
| 11 | Environment variable missing | Runtime crash from `undefined` env var | ~3% of cases | Add env vars to build environment; prefix with `NEXT_PUBLIC_` for client [src1, src2] |
| 12 | Case sensitivity (Linux CI) | `Module not found` only in CI, works locally | ~2% of cases | Match exact file/folder casing in all imports [src5, src6] |

## Decision Tree

> Full script: [decision-tree.txt](scripts/decision-tree.txt) (38 lines)

```
START
├── Using Next.js 16 with custom webpack config?
│   ├── YES → Migrate to turbopack.rules or use --webpack flag [src3, src7]
│   └── NO ↓
├── Error contains "Type error" or "TS"?
│   ├── YES → Is it "Promise<any> is not assignable"?
│   │   ├── YES → Await params/searchParams (Next.js 15+ async API change) [src4]
│   │   └── NO → Fix the type, or check tsconfig.json strict settings [src5]
│   └── NO ↓
├── Error contains "Module not found"?
│   ├── YES → Check: is the package installed? Is the import path correct?
│   │   ├── Works locally, fails in CI → Case sensitivity issue (Linux is case-sensitive) [src6]
│   │   ├── Using path alias (@/) → Verify tsconfig.json paths + next.config.js [src2]
│   │   └── Using Node.js API (fs, path) in client code → Move to server-only code [src1]
│   └── NO ↓
├── Error contains "window is not defined" or "document is not defined"?
│   ├── YES → Server/client boundary violation
│   │   ├── App Router → Add "use client" directive to component [src1]
│   │   └── Pages Router → Wrap in useEffect or use next/dynamic with ssr: false [src6]
│   └── NO ↓
├── Error contains "prerendering" or "getStaticPaths"?
│   ├── YES → Static generation error
│   │   ├── API not available at build time → Use fallback: true or ISR [src1]
│   │   ├── Dynamic route missing getStaticPaths → Add it, or use getServerSideProps [src1]
│   │   └── Data fetching throws → Add try/catch, check env vars for DB/API URLs [src6]
│   └── NO ↓
├── Error contains "ESLint"?
│   ├── YES → Fix lint errors or add eslint: { ignoreDuringBuilds: true } [src2]
│   └── NO ↓
├── Error contains "heap" or "FATAL ERROR" or "out of memory"?
│   ├── YES → NODE_OPTIONS='--max-old-space-size=4096' next build [src8]
│   └── NO ↓
├── Error contains "Invalid src prop" (images)?
│   ├── YES → Add hostname to images.remotePatterns in next.config.js [src2]
│   └── NO ↓
├── Error contains "Mismatching @next/swc version"?
│   ├── YES → Delete node_modules and package-lock.json, run npm install [src1]
│   └── NO ↓
└── DEFAULT → Run next build with NEXT_DEBUG_LOGGING=1, check full stack trace
```

## Step-by-Step Guide

### 1. Reproduce the build failure locally

Always reproduce the error locally before debugging. Dev mode (`next dev`) is lenient — production build (`next build`) enforces strict checks. [src6]

```bash
# Clean build — remove cached artifacts first
rm -rf .next node_modules/.cache
npx next build
```

**Verify**: Error should appear in terminal output with a file path and line number.

### 2. Enable verbose build logging

Get more detail on what's happening during the build. [src1]

```bash
# Verbose debug output
NEXT_DEBUG_LOGGING=1 npx next build --debug

# On Windows PowerShell
$env:NEXT_DEBUG_LOGGING=1; npx next build --debug
```

**Verify**: Build output now includes detailed webpack/turbopack compilation info and page generation steps.

### 3. Check Turbopack compatibility (Next.js 16+)

Next.js 16 made Turbopack the default bundler for both dev and build. If you have custom webpack configuration, it will be silently ignored. [src3, src7]

```bash
# If build fails with Turbopack, test with webpack fallback
npx next build --webpack

# If --webpack works, migrate your webpack config to turbopack format
# In next.config.js:
```

```javascript
/** @type {import('next').NextConfig} */
const nextConfig = {
  // Turbopack-specific configuration (replaces webpack config)
  turbopack: {
    rules: {
      '*.svg': {
        loaders: ['@svgr/webpack'],
        as: '*.js',
      },
    },
    resolveAlias: {
      // Replace webpack aliases
      'old-package': 'new-package',
    },
  },
};
module.exports = nextConfig;
```

**Verify**: `npx next build` completes without Turbopack errors, or `npx next build --webpack` works as fallback.

### 4. Fix async params/searchParams (Next.js 15+)

Next.js 15 changed `params` and `searchParams` to async APIs that return Promises. Using them synchronously causes TypeScript build errors. [src4]

```typescript
// ❌ WRONG (Next.js 14 style — fails in Next.js 15+)
export default function Page({ params }: { params: { id: string } }) {
  return <div>{params.id}</div>;
}

// ✅ CORRECT (Next.js 15+ style — await the Promise)
export default async function Page({
  params,
}: {
  params: Promise<{ id: string }>;
}) {
  const { id } = await params;
  return <div>{id}</div>;
}
```

**Verify**: `npx next build` completes without `Promise<any> is not assignable` errors.

### 5. Fix TypeScript errors

TypeScript errors are treated as fatal by default in `next build`. Fix each error, or as a temporary escape hatch, disable enforcement. [src5]

```typescript
// next.config.js — TEMPORARY escape hatch (not recommended for production)
/** @type {import('next').NextConfig} */
const nextConfig = {
  typescript: {
    ignoreBuildErrors: true,  // Only use to unblock deploy while fixing types
  },
};
module.exports = nextConfig;
```

Better approach — fix the actual type errors:

```typescript
// ❌ WRONG — implicit any causes build error in strict mode
function fetchData(id) { /* ... */ }

// ✅ CORRECT — explicit types
function fetchData(id: string): Promise<Data> { /* ... */ }
```

**Verify**: `npx next build` completes without TypeScript errors.

### 6. Resolve module not found errors

Check the exact error message for the module path, then trace the cause. [src1, src6]

```bash
# Check if the package is installed
npm ls <package-name>

# If missing, install it
npm install <package-name>

# If using path aliases, verify tsconfig.json
cat tsconfig.json | grep -A5 '"paths"'
```

For case sensitivity issues (works on macOS/Windows, fails on Linux CI):

```bash
# Find case mismatches in imports
grep -rn "from ['\"]" --include="*.tsx" --include="*.ts" src/ | \
  sort | head -50
# Compare with actual file names
find src/ -name "*.tsx" -o -name "*.ts" | sort
```

**Verify**: `npx next build` resolves all modules successfully.

### 7. Fix server/client boundary violations

In the App Router, all components are Server Components by default. Browser APIs (`window`, `document`, `localStorage`) are unavailable on the server. [src1, src6]

```jsx
// ❌ WRONG — window is not defined on the server
// app/components/Navbar.jsx (Server Component by default)
export default function Navbar() {
  const isMobile = window.innerWidth < 768;  // CRASH
  return <nav>{isMobile ? 'Mobile' : 'Desktop'}</nav>;
}

// ✅ CORRECT — add 'use client' and use useEffect
// app/components/Navbar.jsx
'use client';
import { useState, useEffect } from 'react';

export default function Navbar() {
  const [isMobile, setIsMobile] = useState(false);
  useEffect(() => {
    setIsMobile(window.innerWidth < 768);
  }, []);
  return <nav>{isMobile ? 'Mobile' : 'Desktop'}</nav>;
}
```

**Verify**: `npx next build` completes without `window is not defined` errors.

### 8. Fix static generation errors

When `next build` pre-renders pages, it runs your data fetching code at build time. APIs or databases must be available. [src1, src6]

```jsx
// Pages Router — getStaticPaths required for dynamic [id] routes
export async function getStaticPaths() {
  try {
    const res = await fetch('https://api.example.com/posts');
    const posts = await res.json();
    return {
      paths: posts.map((post) => ({ params: { id: String(post.id) } })),
      fallback: 'blocking',  // Generate unknown paths on-demand
    };
  } catch (error) {
    // Fallback: generate no pages at build time, all on-demand
    return { paths: [], fallback: 'blocking' };
  }
}

// App Router — generateStaticParams equivalent
export async function generateStaticParams() {
  try {
    const posts = await fetch('https://api.example.com/posts').then(r => r.json());
    return posts.map((post) => ({ id: String(post.id) }));
  } catch {
    return [];  // Empty = generate all on-demand [src1]
  }
}
```

**Verify**: `npx next build` completes static generation without API errors.

### 9. Fix out-of-memory crashes

Large apps with many pages or heavy dependencies can exhaust the default Node.js heap. [src8]

```bash
# Increase Node.js memory limit for build
NODE_OPTIONS='--max-old-space-size=4096' npx next build

# Or set in package.json
# "scripts": { "build": "NODE_OPTIONS='--max-old-space-size=4096' next build" }

# Analyze bundle to find large dependencies
npm install --save-dev @next/bundle-analyzer
# Then in next.config.js:
# const withBundleAnalyzer = require('@next/bundle-analyzer')({ enabled: true });
# module.exports = withBundleAnalyzer(nextConfig);
```

**Verify**: Build completes without FATAL ERROR. Check bundle report for oversized chunks.

## Code Examples

### Next.js App Router: Proper server/client component splitting

> Full script: [next-js-app-router-proper-server-client-component-.jsx](scripts/next-js-app-router-proper-server-client-component-.jsx) (30 lines)

```jsx
// Input:  Component using browser APIs that fails during next build
// Output: Properly split server + client components
// app/layout.tsx — Server Component (default)
import ClientNav from './components/ClientNav';
export default function RootLayout({ children }) {
# ... (see full script)
```

### next.config.js: Common build-fixing configurations

> Full script: [next-config-js-common-build-fixing-configurations.js](scripts/next-config-js-common-build-fixing-configurations.js) (34 lines)

```javascript
// Input:  next.config.js causing or preventing build errors
// Output: Properly configured next.config.js with error handling
/** @type {import('next').NextConfig} */
const nextConfig = {
  // Image optimization: allow external image domains
# ... (see full script)
```

### Next.js 15+ async params migration

```typescript
// Input:  Next.js 14 dynamic route page with sync params
// Output: Next.js 15+ compatible page with async params

// app/blog/[slug]/page.tsx — Next.js 15+ pattern [src4]
type Props = {
  params: Promise<{ slug: string }>;
  searchParams: Promise<{ [key: string]: string | string[] | undefined }>;
};

export default async function BlogPost({ params, searchParams }: Props) {
  const { slug } = await params;
  const { page } = await searchParams;
  const post = await getPost(slug);
  return <article><h1>{post.title}</h1></article>;
}

// For client components that need params, use the useParams hook instead:
// 'use client';
// import { useParams } from 'next/navigation';
// const { slug } = useParams();
```

### next.config.js: Turbopack migration from webpack (Next.js 16)

```javascript
// Input:  next.config.js with custom webpack config (breaks in Next.js 16)
// Output: Turbopack-compatible configuration [src3, src7]

/** @type {import('next').NextConfig} */
const nextConfig = {
  // Turbopack config (replaces webpack customization in Next.js 16+)
  turbopack: {
    rules: {
      '*.svg': {
        loaders: ['@svgr/webpack'],
        as: '*.js',
      },
    },
    resolveAlias: {
      // Replicate webpack resolve.alias
      '@components': './src/components',
    },
    resolveExtensions: ['.tsx', '.ts', '.jsx', '.js', '.json'],
  },

  // Image optimization remains the same
  images: {
    remotePatterns: [
      { protocol: 'https', hostname: 'cdn.example.com' },
    ],
  },

  // Output: standalone for Docker deployments
  output: 'standalone',
};

module.exports = nextConfig;
```

### CI/CD: Build script with proper env and memory

```bash
#!/bin/bash
# Input:  CI/CD build script for Next.js
# Output: Robust build with error handling, memory management

set -euo pipefail

echo "=== Next.js Production Build ==="
echo "Node: $(node -v)"
echo "npm: $(npm -v)"

# Step 1: Clean previous build artifacts
rm -rf .next

# Step 2: Install dependencies (CI should use ci for deterministic installs)
npm ci

# Step 3: Validate environment variables
REQUIRED_VARS=("DATABASE_URL" "NEXT_PUBLIC_API_URL" "API_SECRET")
for var in "${REQUIRED_VARS[@]}"; do
  if [ -z "${!var:-}" ]; then
    echo "ERROR: Required env var $var is not set"
    exit 1
  fi
done

# Step 4: Build with increased memory
NODE_OPTIONS='--max-old-space-size=4096' npx next build

echo "Build completed successfully"
```

## Anti-Patterns

### Wrong: Ignoring TypeScript errors globally

```typescript
// ❌ BAD — hides real type bugs, tech debt builds up [src5]
// next.config.js
module.exports = {
  typescript: { ignoreBuildErrors: true },
  eslint: { ignoreDuringBuilds: true },
};
```

### Correct: Fix types, use strict config

```typescript
// ✅ GOOD — fix actual errors, maintain type safety [src5]
// tsconfig.json
{
  "compilerOptions": {
    "strict": true,
    "noUncheckedIndexedAccess": true,
    "forceConsistentCasingInFileNames": true  // catches case issues
  }
}
// Then fix all reported type errors one by one
```

### Wrong: Using Node.js APIs in client components

```jsx
// ❌ BAD — fs doesn't exist in the browser [src1, src6]
// app/components/FileViewer.tsx
'use client';
import fs from 'fs';

export default function FileViewer() {
  const content = fs.readFileSync('./data.json', 'utf-8');
  return <pre>{content}</pre>;
}
```

### Correct: Move server-only code to server components or API routes

```jsx
// ✅ GOOD — read files on the server, pass data as props [src1]
// app/page.tsx (Server Component — no 'use client')
import fs from 'fs';
import path from 'path';

export default function Page() {
  const filePath = path.join(process.cwd(), 'data.json');
  const content = fs.readFileSync(filePath, 'utf-8');
  const data = JSON.parse(content);
  return <pre>{JSON.stringify(data, null, 2)}</pre>;
}
```

### Wrong: Missing fallback in getStaticPaths

```jsx
// ❌ BAD — build fails if API is down or returns incomplete data [src1]
export async function getStaticPaths() {
  const res = await fetch('https://api.example.com/posts');
  const posts = await res.json();
  return {
    paths: posts.map(p => ({ params: { id: p.id } })),
    fallback: false,  // No fallback = 404 for any path not in list
  };
}
```

### Correct: Use fallback with error handling

```jsx
// ✅ GOOD — graceful fallback, error handling [src1, src6]
export async function getStaticPaths() {
  try {
    const res = await fetch('https://api.example.com/posts');
    if (!res.ok) throw new Error(`API returned ${res.status}`);
    const posts = await res.json();
    return {
      paths: posts.slice(0, 50).map(p => ({ params: { id: String(p.id) } })),
      fallback: 'blocking',  // Unknown paths rendered on-demand
    };
  } catch (error) {
    console.error('getStaticPaths failed:', error);
    return { paths: [], fallback: 'blocking' };
  }
}
```

### Wrong: Using sync params in Next.js 15+ dynamic routes

```typescript
// ❌ BAD — params is now a Promise in Next.js 15+, causes type error [src4]
export default function Page({ params }: { params: { id: string } }) {
  return <div>{params.id}</div>;
}
```

### Correct: Await async params

```typescript
// ✅ GOOD — properly handle async params [src4]
export default async function Page({
  params,
}: {
  params: Promise<{ id: string }>;
}) {
  const { id } = await params;
  return <div>{id}</div>;
}
```

## Common Pitfalls

- **Dev works, build fails**: `next dev` skips TypeScript type checking, doesn't pre-render pages, and is lenient with imports. Always test with `next build` before deploying. [src6]
- **Case sensitivity across OS**: macOS/Windows file systems are case-insensitive (`MyComponent.tsx` === `mycomponent.tsx`). Linux (CI/CD servers) is case-sensitive. Fix: enable `forceConsistentCasingInFileNames: true` in `tsconfig.json`. [src5, src6]
- **`NEXT_PUBLIC_` prefix forgotten**: Environment variables without `NEXT_PUBLIC_` prefix are not available in client-side code. The value will be `undefined` at runtime, potentially crashing the build during pre-rendering. [src1, src2]
- **Stale `.next` cache**: Cached build artifacts can cause phantom errors that don't match your current code. Fix: `rm -rf .next` before building. [src6]
- **`devDependencies` wrongly used**: If a package needed at build-time is in `devDependencies` and your CI uses `npm install --production`, it won't be available. Fix: move it to `dependencies` or ensure CI installs all deps. [src6]
- **Dynamic imports with wrong path**: `next/dynamic(() => import('./path'))` — the path must be a static string literal. Variables or template literals in import paths cause webpack to fail. [src1]
- **Turbopack + webpack config now hard-errors (Next.js 16 latest)**: Earlier Next.js 16 releases silently ignored webpack config; recent patch releases throw `This build is using Turbopack, with a webpack config and no turbopack config` and refuse to build. Fix: migrate to `turbopack.rules`, add an empty `turbopack: {}` block to acknowledge the migration, or use `--webpack` flag. [src3, src7, src9]
- **Turbopack plugin incompatibility**: Common webpack-based plugins (`next-images`, `next-fonts`, `next-sitemap`, custom analytics/bundle-analyzer plugins) have no Turbopack equivalent yet. Fix: run `npx next build --webpack` to opt out, or replace the plugin with a Turbopack-native alternative. [src9]
- **CSS / SCSS resolution changes**: Next.js 16 tightened CSS handling — global stylesheets must be inside `app/` or `src/` and imported from `app/layout.{js,tsx}`. Imports from outside that tree fail with `Module not found: Can't resolve '../assets/css/style.scss'`. Fix: move styles inside `app/` and import in the root layout. [src9]
- **`Unable to acquire lock at .next/dev/lock`**: A previous dev or build process didn't shut down cleanly, leaving a lock file Turbopack refuses to overwrite. Fix: `rm -rf .next` then re-run. [src9]
- **`npm link` breaks under Turbopack**: Next.js 16's default Turbopack does not follow symlinks to directories outside the project root, so locally-linked packages fail with `Module not found`. Fix: use `--webpack` for local dev with linked packages, or publish a local workspace via npm/pnpm workspaces instead. [src9]
- **SWC version mismatch**: Mismatching `@next/swc` version warnings after partial upgrades. Fix: delete `node_modules` and `package-lock.json`, then `npm install`. [src1]

## Diagnostic Commands

```bash
# Clean build (remove cached artifacts)
rm -rf .next node_modules/.cache

# Build with verbose logging
NEXT_DEBUG_LOGGING=1 npx next build --debug 2>&1 | tee build.log

# Build with increased memory (4GB)
NODE_OPTIONS='--max-old-space-size=4096' npx next build

# Build with webpack fallback (Next.js 16+ when Turbopack fails)
npx next build --webpack

# Check Node.js version compatibility
node -v  # Must be >= 18.18.0 for Next.js 15+, >= 20.x for Next.js 16

# Check for TypeScript errors without building
npx tsc --noEmit

# Check for ESLint errors without building
npx next lint

# Analyze bundle size (install @next/bundle-analyzer first)
ANALYZE=true npx next build

# Verify environment variables are set
env | grep NEXT_PUBLIC_ | sort

# Find case-sensitive import mismatches
find src/ app/ -type f \( -name "*.tsx" -o -name "*.ts" \) | sort > /tmp/files.txt
grep -roh "from ['\"][^'\"]*['\"]" src/ app/ --include="*.ts" --include="*.tsx" | sort > /tmp/imports.txt

# Check for SWC version mismatch
npm ls @next/swc-linux-x64-gnu @next/swc-darwin-arm64 2>/dev/null

# Run Next.js upgrade codemod (for version migrations)
npx @next/codemod@latest upgrade
```

## Version History & Compatibility

| Version | Build Behavior | Key Changes |
|---|---|---|
| Next.js 16 (React 19) | Current | Turbopack default for dev + build, `--webpack` fallback, filesystem caching, 2-5x faster builds [src3, src7] |
| Next.js 15 (React 19) | Supported | Async request APIs (`params`, `searchParams` return Promises), caching uncached by default, stricter build validation [src4] |
| Next.js 14 (React 18) | Supported | App Router stable, Server Actions stable, `next/image` improvements [src2] |
| Next.js 13 (React 18) | Supported | App Router introduced (beta), `app/` directory, React Server Components [src1] |
| Next.js 12 (React 17-18) | Legacy | Pages Router only, SWC compiler default, middleware [src2] |
| Next.js 11 and below | EOL | Babel-based compilation, older React versions |

## When to Use / When Not to Use

| Use When | Don't Use When | Use Instead |
|---|---|---|
| `next build` exits with non-zero code | App runs fine but is slow | Performance optimization guide |
| Build passes locally but fails in CI/CD | Runtime error after successful build | React error boundary / debugging guide |
| Error during static page generation | Hydration mismatch warning (app still works) | Hydration mismatch guide |
| TypeScript or ESLint blocking build | Styling or CSS issues at runtime | CSS debugging guide |
| Turbopack build fails in Next.js 16 | Turbopack dev server slow (not a build error) | Turbopack performance docs |

## Important Caveats

- Next.js 16 makes Turbopack the default bundler for both `next dev` and `next build`. Recent 16.x patch releases now hard-error on a webpack-only `next.config.js` (`This build is using Turbopack, with a webpack config and no turbopack config`) instead of silently ignoring it. Use `--webpack` to opt out, migrate to `turbopack.rules`, or add an empty `turbopack: {}` block to acknowledge the migration. [src3, src9]
- Next.js 15 changed `params` and `searchParams` to async APIs returning Promises. This is a breaking change that causes TypeScript build errors. Run `npx @next/codemod@latest upgrade` to automate the migration. [src4]
- The App Router (`app/`) and Pages Router (`pages/`) can coexist, but have different build behaviors. `app/` treats all components as Server Components by default; `pages/` does not.
- `typescript: { ignoreBuildErrors: true }` is a dangerous escape hatch — it hides real bugs. Use it only as a temporary measure while fixing types incrementally. [src5]
- Environment variables used in `getStaticProps` or Server Components must be available at build time, not just runtime. Verify they're set in your CI/CD build environment. [src1]
- Node.js 18.18.0 is the minimum for Next.js 15+; Node.js 20.x is recommended for Next.js 16. Using older versions causes cryptic build failures.
- Turbopack does not support all webpack loaders. Check the Turbopack documentation for supported loaders before migrating. Some loaders need `turbopack.rules` configuration. [src7]

## Related Units

- [React Hydration Mismatch](/software/debugging/react-hydration-mismatch/2026)
- [React White Screen of Death](/software/debugging/react-white-screen/2026)
- [React Too Many Re-Renders](/software/debugging/react-too-many-rerenders/2026)
- [Webpack and Vite Build Failures](/software/debugging/webpack-vite-build-failures/2026)
- [Create React App to Next.js Migration](/software/migrations/cra-to-nextjs/2026)
