---
title: "Dev Error Overlay"
description: "The Dev Error Overlay is Next.js's browser-based diagnostic interface designed to capture, transform, and render runtime errors, unhandled rejections, console errors, and hydration mismatches durin..."
last_updated: "2026-09-23T10:52:03.186406+00:00"
canonical_url: "https://www.doc0.dev/docs/8f4009b0-65bd-4480-9b00-e201f0914bb3/technical/development-and-diagnostics/dev-error-overlay"
---

<details>
<summary>Relevant source files</summary>

The following files were used as context for generating this wiki page:

- [packages/next/src/server/patch-error-inspect.ts](https://github.com/blade47/next.js/blob/main/packages/next/src/server/patch-error-inspect.ts)
- [packages/next/src/server/dev/middleware-webpack.ts](https://github.com/blade47/next.js/blob/main/packages/next/src/server/dev/middleware-webpack.ts)
- [packages/next/src/server/dev/middleware-turbopack.ts](https://github.com/blade47/next.js/blob/main/packages/next/src/server/dev/middleware-turbopack.ts)
- [packages/next/src/next-devtools/userspace/pages/pages-dev-overlay-setup.tsx](https://github.com/blade47/next.js/blob/main/packages/next/src/next-devtools/userspace/pages/pages-dev-overlay-setup.tsx)
- [packages/next/src/server/dev/browser-logs/source-map.ts](https://github.com/blade47/next.js/blob/main/packages/next/src/server/dev/browser-logs/source-map.ts)
- [packages/next/src/next-devtools/dev-overlay.browser.tsx](https://github.com/blade47/next.js/blob/main/packages/next/src/next-devtools/dev-overlay.browser.tsx)
- [packages/next/src/server/lib/source-maps.ts](https://github.com/blade47/next.js/blob/main/packages/next/src/server/lib/source-maps.ts)
- [packages/next/src/server/lib/install-code-frame.ts](https://github.com/blade47/next.js/blob/main/packages/next/src/server/lib/install-code-frame.ts)
- [packages/next/src/next-devtools/userspace/app/errors/stitched-error.ts](https://github.com/blade47/next.js/blob/main/packages/next/src/next-devtools/userspace/app/errors/stitched-error.ts)
- [packages/next/src/next-devtools/dev-overlay/components/code-frame/code-frame.tsx](https://github.com/blade47/next.js/blob/main/packages/next/src/next-devtools/dev-overlay/components/code-frame/code-frame.tsx)
- [packages/next/src/next-devtools/dev-overlay/container/errors.tsx](https://github.com/blade47/next.js/blob/main/packages/next/src/next-devtools/dev-overlay/container/errors.tsx)
- [packages/next/src/next-devtools/userspace/app/errors/use-error-handler.ts](https://github.com/blade47/next.js/blob/main/packages/next/src/next-devtools/userspace/app/errors/use-error-handler.ts)
- [packages/next/src/next-devtools/dev-overlay/dev-overlay.tsx](https://github.com/blade47/next.js/blob/main/packages/next/src/next-devtools/dev-overlay/dev-overlay.tsx)
- [packages/next/src/client/react-client-callbacks/error-boundary-callbacks.ts](https://github.com/blade47/next.js/blob/main/packages/next/src/client/react-client-callbacks/error-boundary-callbacks.ts)
- [packages/next/src/next-devtools/shared/stack-frame.ts](https://github.com/blade47/next.js/blob/main/packages/next/src/next-devtools/shared/stack-frame.ts)
- [packages/next/src/next-devtools/userspace/app/app-dev-overlay-error-boundary.tsx](https://github.com/blade47/next.js/blob/main/packages/next/src/next-devtools/userspace/app/app-dev-overlay-error-boundary.tsx)
- [packages/next/src/next-devtools/userspace/app/forward-logs.ts](https://github.com/blade47/next.js/blob/main/packages/next/src/next-devtools/userspace/app/forward-logs.ts)
- [packages/next/src/next-devtools/userspace/pages/hydration-error-state.ts](https://github.com/blade47/next.js/blob/main/packages/next/src/next-devtools/userspace/pages/hydration-error-state.ts)
- [packages/next/src/next-devtools/userspace/app/app-dev-overlay-setup.ts](https://github.com/blade47/next.js/blob/main/packages/next/src/next-devtools/userspace/app/app-dev-overlay-setup.ts)
- [packages/next/src/next-devtools/dev-overlay/utils/get-error-by-type.ts](https://github.com/blade47/next.js/blob/main/packages/next/src/next-devtools/dev-overlay/utils/get-error-by-type.ts)
- [packages/next/src/next-devtools/server/shared.ts](https://github.com/blade47/next.js/blob/main/packages/next/src/next-devtools/server/shared.ts)
- [packages/next/src/next-devtools/dev-overlay/components/call-stack-frame/call-stack-frame.tsx](https://github.com/blade47/next.js/blob/main/packages/next/src/next-devtools/dev-overlay/components/call-stack-frame/call-stack-frame.tsx)
- [packages/next/src/next-devtools/dev-overlay/container/runtime-error/index.tsx](https://github.com/blade47/next.js/blob/main/packages/next/src/next-devtools/dev-overlay/container/runtime-error/index.tsx)
- [packages/next/src/next-devtools/dev-overlay/components/code-frame/parse-code-frame.ts](https://github.com/blade47/next.js/blob/main/packages/next/src/next-devtools/dev-overlay/components/code-frame/parse-code-frame.ts)
- [packages/next/src/next-devtools/userspace/app/errors/intercept-console-error.ts](https://github.com/blade47/next.js/blob/main/packages/next/src/next-devtools/userspace/app/errors/intercept-console-error.ts)
- [packages/next/src/next-devtools/userspace/app/client-entry.tsx](https://github.com/blade47/next.js/blob/main/packages/next/src/next-devtools/userspace/app/client-entry.tsx)
- [packages/next/src/next-devtools/dev-overlay/components/errors/error-overlay-call-stack/error-overlay-call-stack.tsx](https://github.com/blade47/next.js/blob/main/packages/next/src/next-devtools/dev-overlay/components/errors/error-overlay-call-stack/error-overlay-call-stack.tsx)
- [packages/next/src/server/dev/node-stack-frames.ts](https://github.com/blade47/next.js/blob/main/packages/next/src/server/dev/node-stack-frames.ts)
- [packages/next/src/next-devtools/dev-overlay/utils/generate-error-info.ts](https://github.com/blade47/next.js/blob/main/packages/next/src/next-devtools/dev-overlay/utils/generate-error-info.ts)
- [packages/next/src/server/node-environment-extensions/error-inspect.tsx](https://github.com/blade47/next.js/blob/main/packages/next/src/server/node-environment-extensions/error-inspect.tsx)
</details>

## Overview

The Dev Error Overlay is Next.js's browser-based diagnostic interface designed to capture, transform, and render runtime errors, unhandled rejections, console errors, and hydration mismatches during development. When an application throws an uncaught error in either the App or Pages router, the overlay intercepts the failure, sanitizes and decorates the error instance, fetches sourcemapped original code locations from the dev server, and presents an interactive stack trace accompanied by a highlighted code frame.

By bridging client-side runtime boundaries with server-side bundler statistics (Webpack and Turbopack), the overlay resolves obfuscated production-style chunks back to original developer source files. It implements specialized handling for React hydration mismatches, error cause chains (`error.cause`), aggregate errors (`AggregateError`), and frame ignore-lists (`node_modules` or anonymous wrappers) to ensure developers focus exclusively on first-party application logic.

Sources: [packages/next/src/next-devtools/dev-overlay.browser.tsx:189-200](https://github.com/blade47/next.js/blob/main/packages/next/src/next-devtools/dev-overlay.browser.tsx#L189-L200)

```mermaid
flowchart TD
  Error[Uncaught Error / Rejection / Console.error] --> Capture[Userspace Event Listeners]
  Capture --> Dispatch[Dispatcher & Queue Manager]
  Dispatch --> OverlayRoot[DevOverlayRoot & Reducer State]
  OverlayRoot --> FetchFrames[POST /__nextjs_original-stack-frames]
  FetchFrames --> Bundler{Bundler Context}
  Bundler -->|Webpack| WebpackMap[middleware-webpack.ts]
  Bundler -->|Turbopack| TurboMap[middleware-turbopack.ts]
  WebpackMap --> Render[CodeFrame & ErrorOverlayCallStack]
  TurboMap --> Render
```

Sources: [packages/next/src/server/dev/browser-logs/source-map.ts:32-77](https://github.com/blade47/next.js/blob/main/packages/next/src/server/dev/browser-logs/source-map.ts#L32-L77)

---

## Client-Side Error Interception and Dispatching

The Dev Error Overlay initializes event listeners in the browser environment to intercept global errors, unhandled promise rejections, and intercepted console errors. In the App Router, this setup is bootstrapped via `handleGlobalErrors()` and `patchConsoleError()`, while the Pages router mounts `PagesDevOverlayBridge`.

Sources: [packages/next/src/next-devtools/userspace/app/errors/use-error-handler.ts:121-131](https://github.com/blade47/next.js/blob/main/packages/next/src/next-devtools/userspace/app/errors/use-error-handler.ts#L121-L131), [packages/next/src/next-devtools/userspace/pages/pages-dev-overlay-setup.tsx:112-126](https://github.com/blade47/next.js/blob/main/packages/next/src/next-devtools/userspace/pages/pages-dev-overlay-setup.tsx#L112-L126)

When an unhandled error or rejection occurs, the event handler wraps or coerces the thrown value into a standard `Error` instance, attaches React owner stacks if available via `setOwnerStackIfAvailable()`, and enqueues microtasks to pass the error to the active overlay state handlers without blocking synchronous component rendering.

Sources: [packages/next/src/next-devtools/userspace/app/errors/stitched-error.ts:13-28](https://github.com/blade47/next.js/blob/main/packages/next/src/next-devtools/userspace/app/errors/stitched-error.ts#L13-L28), [packages/next/src/next-devtools/userspace/app/errors/use-error-handler.ts:22-57](https://github.com/blade47/next.js/blob/main/packages/next/src/next-devtools/userspace/app/errors/use-error-handler.ts#L22-L57)

> [!NOTE]
> Events dispatched during module evaluation or early lifecycle phases before React establishes its dispatch function are buffered into a local queue (`queue`) and replayed via `replayQueuedEvents()` once `maybeDispatch` is bound in `useInsertionEffect`.

Sources: [packages/next/src/next-devtools/dev-overlay.browser.tsx:128-142](https://github.com/blade47/next.js/blob/main/packages/next/src/next-devtools/dev-overlay.browser.tsx#L128-L142), [packages/next/src/next-devtools/dev-overlay.browser.tsx:242-251](https://github.com/blade47/next.js/blob/main/packages/next/src/next-devtools/dev-overlay.browser.tsx#L242-L251)

```typescript
// Example usage: Registering and dispatching an unhandled client error
import { handleClientError } from '../next-devtools/userspace/app/errors/use-error-handler'

try {
  // Application code that throws a runtime exception
  throw new Error('Failed to execute client operation')
} catch (err) {
  handleClientError(err as Error)
}
```

Sources: [packages/next/src/next-devtools/userspace/app/errors/use-error-handler.ts:48-57](https://github.com/blade47/next.js/blob/main/packages/next/src/next-devtools/userspace/app/errors/use-error-handler.ts#L48-L57)

---

## Stack Trace Parsing and Server-Side Resolution

Raw stack traces captured in the browser contain obfuscated bundle paths (e.g., `_next/static/chunks/...`). To map these back to original author-time source files, the Dev Error Overlay transmits raw `StackFrame` structures to the development server via a `POST` request to `/__nextjs_original-stack-frames`.

Sources: [packages/next/src/next-devtools/shared/stack-frame.ts:82-103](https://github.com/blade47/next.js/blob/main/packages/next/src/next-devtools/shared/stack-frame.ts#L82-L103)

The server-side overlay middleware (`middleware-webpack.ts` or `middleware-turbopack.ts`) inspects the target compilation stats or Turbopack trace engine, resolves line and column positions against applicable source map payloads, and computes original stack frames and code frames.

Sources: [packages/next/src/server/dev/middleware-webpack.ts:607-630](https://github.com/blade47/next.js/blob/main/packages/next/src/server/dev/middleware-webpack.ts#L607-L630), [packages/next/src/server/dev/middleware-turbopack.ts:364-374](https://github.com/blade47/next.js/blob/main/packages/next/src/server/dev/middleware-turbopack.ts#L364-L374)

```mermaid
sequenceDiagram
  participant Client as Browser Overlay
  participant Server as Dev Server Middleware
  participant Bundler as Webpack / Turbopack Stats
  Client->>Server: POST /__nextjs_original-stack-frames
  Server->>Bundler: Query compilation chunks & source maps
  Bundler-->>Server: Return original position & code content
  Server-->>Client: Return OriginalStackFrameResponse[]
```

Sources: [packages/next/src/next-devtools/shared/stack-frame.ts:97-112](https://github.com/blade47/next.js/blob/main/packages/next/src/next-devtools/shared/stack-frame.ts#L97-L112), [packages/next/src/server/dev/middleware-webpack.ts:611-630](https://github.com/blade47/next.js/blob/main/packages/next/src/server/dev/middleware-webpack.ts#L611-L630)

---

## Bundler Integration: Webpack vs. Turbopack

The overlay abstracts bundler differences by routing mapping requests through `mapFramesUsingBundler()`. 

Sources: [packages/next/src/server/dev/browser-logs/source-map.ts:32-35](https://github.com/blade47/next.js/blob/main/packages/next/src/server/dev/browser-logs/source-map.ts#L32-L35)

- **Webpack:** Iterates through compilation targets in priority order (Client compilation first for Pages; Client, Server, then Edge Server compilations for App Router depending on rendering context) using `clientStats()`, `serverStats()`, and `edgeServerStats()`.

Sources: [packages/next/src/server/dev/middleware-webpack.ts:481-516](https://github.com/blade47/next.js/blob/main/packages/next/src/server/dev/middleware-webpack.ts#L481-L516)

- **Turbopack:** Utilizes native source mapping via `nativeTraceSource()` or falls back to `batchedTraceSource()` to query Turbopack's project state directly.

Sources: [packages/next/src/server/dev/middleware-turbopack.ts:303-307](https://github.com/blade47/next.js/blob/main/packages/next/src/server/dev/middleware-turbopack.ts#L303-L307)

| Bundler Strategy | Target Compilations Checked | Source Mapping Mechanism |
| :--- | :--- | :--- |
| **Webpack** | Client, Server, Edge Server | `getSource`, `getOriginalStackFrame`, `SourceMapConsumer` |
| **Turbopack** | Project graph & native bindings | `nativeTraceSource`, `batchedTraceSource`, `SourceMapConsumer` |

Sources: [packages/next/src/server/dev/middleware-webpack.ts:477-519](https://github.com/blade47/next.js/blob/main/packages/next/src/server/dev/middleware-webpack.ts#L477-L519), [packages/next/src/server/dev/middleware-turbopack.ts:181-284](https://github.com/blade47/next.js/blob/main/packages/next/src/server/dev/middleware-turbopack.ts#L181-L284)

> [!WARNING]
> If a source map is invalid or malformed, `nativeTraceSource` and `filterStackFrameDEV` catch the parsing error and log a warning without re-entering error inspection loops, preventing infinite error recursion.

Sources: [packages/next/src/server/dev/middleware-turbopack.ts:186-193](https://github.com/blade47/next.js/blob/main/packages/next/src/server/dev/middleware-turbopack.ts#L186-L193), [packages/next/src/server/lib/source-maps.ts:144-154](https://github.com/blade47/next.js/blob/main/packages/next/src/server/lib/source-maps.ts#L144-L154)

---

## Code Frame Parsing, Formatting, and Rendering

Once original stack frames are resolved, the overlay extracts and renders code snippets via the `CodeFrame` component. The raw code frame string is formatted by `formatCodeFrame()`, which strips excess indentation, and tokenized using `Anser` via `groupCodeFrameLines()` to support ANSI styling and class-based theming.

Sources: [packages/next/src/next-devtools/dev-overlay/components/code-frame/code-frame.tsx:18-28](https://github.com/blade47/next.js/blob/main/packages/next/src/next-devtools/dev-overlay/components/code-frame/code-frame.tsx#L18-L28), [packages/next/src/next-devtools/dev-overlay/components/code-frame/parse-code-frame.ts:6-41](https://github.com/blade47/next.js/blob/main/packages/next/src/next-devtools/dev-overlay/components/code-frame/parse-code-frame.ts#L6-L41)

`parseLineNumberFromCodeFrameLine()` parses individual line entries to identify line numbers and highlight errored lines (`data-nextjs-codeframe-line--errored="true"`).

Sources: [packages/next/src/next-devtools/dev-overlay/components/code-frame/parse-code-frame.ts:82-98](https://github.com/blade47/next.js/blob/main/packages/next/src/next-devtools/dev-overlay/components/code-frame/parse-code-frame.ts#L82-L98)

```typescript
// Example usage: Parsing and rendering code frames directly
import { formatCodeFrame, groupCodeFrameLines } from '../next-devtools/dev-overlay/components/code-frame/parse-code-frame'

const rawCodeFrame = `
  1 | function MyComponent() {
> 2 |   throw new Error('Boom')
    |   ^
  3 | }
`
const formatted = formatCodeFrame(rawCodeFrame)
const groupedLines = groupCodeFrameLines(formatted)
```

Sources: [packages/next/src/next-devtools/dev-overlay/components/code-frame/parse-code-frame.ts:6-73](https://github.com/blade47/next.js/blob/main/packages/next/src/next-devtools/dev-overlay/components/code-frame/parse-code-frame.ts#L6-L73)

---

## Hydration Error State Integration

Hydration mismatches between server-rendered HTML and client-side React trees require specialized diagnostics. The overlay captures hydration warnings via `storeHydrationErrorStateFromConsoleArgs()` in `hydration-error-state.ts`, distinguishing between React 18 and React 19 warning signatures.

Sources: [packages/next/src/next-devtools/userspace/pages/hydration-error-state.ts:58-106](https://github.com/blade47/next.js/blob/main/packages/next/src/next-devtools/userspace/pages/hydration-error-state.ts#L58-L106)

For React 18, `generateHydrationDiffReact18()` parses component stack traces from console arguments to build an ASCII tree diff highlighting unexpected server vs. client tag structures or text nodes.

Sources: [packages/next/src/next-devtools/userspace/pages/hydration-error-state.ts:126-186](https://github.com/blade47/next.js/blob/main/packages/next/src/next-devtools/userspace/pages/hydration-error-state.ts#L126-L186)

```typescript
// Example usage: Attaching hydration error state to a runtime error
import { attachHydrationErrorState, getSquashedHydrationErrorDetails } from '../next-devtools/userspace/pages/hydration-error-state'

const error = new Error('Hydration failed because the initial UI does not match what was rendered on the server.')
attachHydrationErrorState(error)
const hydrationDetails = getSquashedHydrationErrorDetails(error)
```

Sources: [packages/next/src/next-devtools/userspace/pages/hydration-error-state.ts:19-54](https://github.com/blade47/next.js/blob/main/packages/next/src/next-devtools/userspace/pages/hydration-error-state.ts#L19-L54)

---

## Error Aggregation, Causes, and Call Stacks

When errors chain multiple nested exceptions or aggregate multiple failures, `getErrorByType()` constructs a structured error tree. 

Sources: [packages/next/src/next-devtools/dev-overlay/utils/get-error-by-type.ts:49-89](https://github.com/blade47/next.js/blob/main/packages/next/src/next-devtools/dev-overlay/utils/get-error-by-type.ts#L49-L89)

- **Cause Chains:** `getCauseChain()` recursively inspects `error.cause` up to a maximum depth of `5`.

Sources: [packages/next/src/next-devtools/dev-overlay/utils/get-error-by-type.ts:91-127](https://github.com/blade47/next.js/blob/main/packages/next/src/next-devtools/dev-overlay/utils/get-error-by-type.ts#L91-L127)

- **Aggregate Errors:** `getAggregateErrors()` unpacks `AggregateError` instances, processing up to `5` child errors (`maxErrors = 5`).

Sources: [packages/next/src/next-devtools/dev-overlay/utils/get-error-by-type.ts:129-180](https://github.com/blade47/next.js/blob/main/packages/next/src/next-devtools/dev-overlay/utils/get-error-by-type.ts#L129-L180)

- **Call Stack Tallying:** `ErrorOverlayCallStack` computes `ignoredFramesTally` and provides an interactive toggle (`onToggleIgnoreList`) that dynamically adjusts container dialog heights using `transitionend` event listeners.

Sources: [packages/next/src/next-devtools/dev-overlay/components/errors/error-overlay-call-stack/error-overlay-call-stack.tsx:17-57](https://github.com/blade47/next.js/blob/main/packages/next/src/next-devtools/dev-overlay/components/errors/error-overlay-call-stack/error-overlay-call-stack.tsx#L17-L57)

> [!IMPORTANT]
> Both `getCauseChain` and `getAggregateErrors` enforce a maximum recursion depth of `5` to prevent stack overflow vulnerabilities and infinite processing loops when handling circular or deeply nested error causes.

Sources: [packages/next/src/next-devtools/dev-overlay/utils/get-error-by-type.ts:91-96](https://github.com/blade47/next.js/blob/main/packages/next/src/next-devtools/dev-overlay/utils/get-error-by-type.ts#L91-L96), [packages/next/src/next-devtools/dev-overlay/utils/get-error-by-type.ts:129-135](https://github.com/blade47/next.js/blob/main/packages/next/src/next-devtools/dev-overlay/utils/get-error-by-type.ts#L129-L135)

## Related

- [DevTools Panel](https://www.doc0.dev/docs/8f4009b0-65bd-4480-9b00-e201f0914bb3/technical/development-and-diagnostics/devtools-panel)
- [Dev Server and HMR](https://www.doc0.dev/docs/8f4009b0-65bd-4480-9b00-e201f0914bb3/technical/development-and-diagnostics/dev-server-and-hmr)


## Sitemap

See the full [sitemap](https://www.doc0.dev/docs/8f4009b0-65bd-4480-9b00-e201f0914bb3/llms.txt) for all pages in this wiki.
