Skip to main content

Has error boundary at root layout

ab-002595 · project-snapshot.error-handling.has-error-boundary
Severity: highactive

Why it matters

Without a root-level error boundary, one unhandled render exception — a null field on an API response, a missing key in a hydration payload, a third-party script that mutates the DOM — takes the entire page to a blank white screen or the framework's raw stack-trace error page. Users can't navigate, can't retry, and often can't even reach a support link. AI coding tools generate React and Next.js apps without app/error.tsx by default because the happy path renders fine and the boundary file isn't required for the app to compile. The recovery experience for users is the whole product during an outage; shipping without a boundary means any single bad render crashes the session with no recovery path short of a manual browser refresh.

Severity rationale

High because a single unhandled exception anywhere in the render tree takes the entire UI down to an unrecoverable blank or framework-default page, with no retry affordance for the user.

Remediation

Create app/error.tsx:

'use client'
export default function Error({ error, reset }) {
  return <div>Something went wrong. <button onClick={reset}>Retry</button></div>
}

Deeper remediation guidance and cross-reference coverage for this check lives in the saas-error-handling Pro audit — run that after applying this fix for a more exhaustive pass on the same topic.

Detection

  • ID: project-snapshot.error-handling.has-error-boundary
  • Severity: high
  • What to look for: For Next.js: check for app/error.tsx (App Router) or pages/_error.tsx (Pages Router). For React: check for an ErrorBoundary component imported into the root layout. For other frameworks: check the framework's equivalent global error handler.
  • Pass criteria: A global error boundary exists at the root layout level.
  • Fail criteria: No error boundary detected at the root.
  • Skip (N/A) when: Project has no React/Vue/Svelte UI tree (API, CLI, library).
  • Do NOT pass when: An error file exists but only throw error — that propagates the error upward instead of catching it.
  • Report even on pass: "Error boundary at {path}; rendering fallback UI on uncaught errors."
  • Detail on fail: "No app/error.tsx or pages/_error.tsx found; uncaught errors will show framework default error UI".
  • Cross-reference: For full error-handling coverage (retry strategies, circuit breakers, structured logging, observability), run the saas-error-handling audit.
  • Remediation: Create app/error.tsx:
    'use client'
    export default function Error({ error, reset }) {
      return <div>Something went wrong. <button onClick={reset}>Retry</button></div>
    }
    

Taxons

History