React error boundary wraps main application
Why it matters
Without a root-level error boundary, a single thrown exception in any React component silently blanks the entire application — users see a white screen with no explanation and no recovery path. CWE-755 (Improper Handling of Exceptional Conditions) names this directly: the absence of fault tolerance at the application boundary turns transient bugs into total outages. For Next.js App Router projects, a route-level error.tsx alone is insufficient — errors in the root layout bypass it entirely, requiring global-error.tsx as a separate boundary. ISO 25010 reliability.fault-tolerance classifies the absence of this pattern as a direct reliability failure.
Severity rationale
Critical because a missing root boundary converts any unhandled render exception into a full application crash with no user-visible recovery path.
Remediation
Add both app/global-error.tsx and app/error.tsx for Next.js App Router — the global file is mandatory because route-level boundaries don't cover root layout errors.
// app/global-error.tsx
'use client'
export default function GlobalError({ error, reset }: { error: Error; reset: () => void }) {
return (
<html>
<body>
<h2>Something went wrong</h2>
<button onClick={() => reset()}>Try again</button>
</body>
</html>
)
}
For non-Next.js React apps, wrap the root render point with react-error-boundary. Verify by intentionally throwing in a component during development and confirming the fallback UI appears instead of a blank page.
Detection
-
ID:
react-error-boundary -
Severity:
critical -
What to look for: Examine whether the application has a top-level error boundary covering the main component tree. For Next.js App Router: check for
src/app/error.tsxorapp/error.tsx(the route-level error boundary) ANDsrc/app/global-error.tsxorapp/global-error.tsx(the root layout error boundary). For Next.js Pages Router: check forpages/_error.tsx. For other React apps (Vite/CRA/Remix/Gatsby): look for a component that extendsReact.Componentand implementscomponentDidCatch/getDerivedStateFromError, or imports fromreact-error-boundary. Check whether the boundary wraps the root render point (e.g.,<App />inmain.tsxor equivalent). -
Pass criteria: Count all error boundary files in the project (error.tsx, global-error.tsx, _error.tsx, ErrorBoundary components). Pass if a root-level error boundary exists and wraps the primary application tree. For Next.js App Router, pass if both
error.tsx(for route errors) andglobal-error.tsx(for root layout errors) are present — at least 2 boundary files required. For Pages Router, pass ifpages/_error.tsxexists. For other React apps, pass if anErrorBoundarycomponent wraps<App />or the equivalent root component. Report even on pass: "Found X error boundary files covering Y route segments." -
Fail criteria: Fail if no error boundary exists at the application root. For Next.js App Router, fail if
global-error.tsxis absent (route-levelerror.tsxalone is insufficient — it doesn't catch errors in the root layout). Do NOT pass when only a route-levelerror.tsxexists withoutglobal-error.tsx— root layout errors will crash the entire app with no fallback. -
Cross-reference: For error boundary fallback UI quality, see the error-boundaries-fallback-ui check in this audit.
-
Skip (N/A) when: The project has no React dependency. Signal:
reactabsent frompackage.jsondependencies/devDependencies, no.jsx/.tsxfiles present, and framework is not Next.js/Remix/Gatsby/Vite-React. -
Detail on fail: Identify which boundary type is missing (e.g., "global-error.tsx not found; route-level error.tsx exists but does not catch root layout errors" or "No ErrorBoundary wrapping root component in main.tsx"). Max 500 chars.
-
Remediation: Your application has no safety net for unexpected rendering errors. When any component throws, the entire page goes blank with no user feedback.
For Next.js App Router, create both files:
// app/global-error.tsx 'use client' export default function GlobalError({ error, reset }: { error: Error; reset: () => void }) { return ( <html> <body> <h2>Something went wrong</h2> <button onClick={() => reset()}>Try again</button> </body> </html> ) }// app/error.tsx 'use client' export default function Error({ error, reset }: { error: Error; reset: () => void }) { return ( <div> <h2>Something went wrong</h2> <button onClick={() => reset()}>Try again</button> </div> ) }For non-Next.js React apps, wrap your root render with
react-error-boundary:import { ErrorBoundary } from 'react-error-boundary' <ErrorBoundary fallback={<div>Something went wrong. <button onClick={() => window.location.reload()}>Reload</button></div>}> <App /> </ErrorBoundary>Verify by intentionally throwing in a component and confirming the fallback UI renders instead of a blank page.
External references
- cwe · CWE-755 — Improper Handling of Exceptional Conditions
- iso-25010:2011 · reliability.fault-tolerance
Taxons
History
- 2026-04-18·v1.0.0·Initial import from saas-error-handling·automated