Without a root error boundary, any unhandled React component error produces a white screen of death — the entire application unmounts silently. Users lose their context, their unsaved work, and often assume the product is broken. ISO 25010 reliability.fault-tolerance requires the system to continue operating under fault conditions; a missing root boundary violates that baseline. One null-pointer in a third-party widget can take down checkout, dashboard, and every other route.
Critical because a single component failure without a root error boundary crashes the entire application for every active user simultaneously.
Add app/error.tsx (Next.js App Router) or wrap your root component with react-error-boundary. The boundary must render a fallback — not just log — to satisfy the pass criteria.
// app/error.tsx — root error boundary
'use client'
export default function Error({
error,
reset,
}: {
error: Error & { digest?: string }
reset: () => void
}) {
return (
<div>
<h1>Something went wrong</h1>
<button onClick={reset}>Try again</button>
</div>
)
}
For non-Next.js apps, wrap your root render in src/main.tsx with <ErrorBoundary FallbackComponent={RootFallback}>.
ID: error-resilience.error-boundaries-ui-recovery.root-error-boundary
Severity: critical
What to look for: Count all error boundary implementations in the application. Enumerate whether a root-level error boundary wraps the entire app in app/error.tsx or equivalent. Search for a root-level error boundary component or configuration. For React apps, look for a component that extends ErrorBoundary or uses react-error-boundary. This should wrap the entire application at the root render point, router, or layout level. Check app.tsx, _app.tsx, main.tsx, layout.tsx, or your root component.
Pass criteria: An error boundary exists at the root level that catches unhandled component errors and renders a fallback UI instead of a blank screen or white screen of death. At least 1 root error boundary must exist that catches all unhandled errors.
Fail criteria: No root-level error boundary found, or an error boundary exists but is not at the root level (only wraps child routes, not the whole app).
Skip (N/A) when: The application has no user-facing UI components (API-only projects) or the framework manages error boundaries automatically with no user interface.
Do NOT pass when: An error boundary exists but only logs the error without rendering a fallback UI, leaving users on a blank screen.
Cross-reference: For feature-level error boundaries, see feature-error-boundaries. For friendly fallback components, see friendly-fallback-components.
Detail on fail: Specify where the gap is. Example: "No error boundary found at root. Unhandled component errors will result in blank screen" or "Error boundary exists in route layout but not at application root — errors in root level components will crash the app"
Remediation: Install a React error boundary library (react-error-boundary is lightweight and widely used) and wrap your application root:
// app/error.tsx — root error boundary
'use client'
export default function Error({ error, reset }: { error: Error; reset: () => void }) {
return <div><h1>Something went wrong</h1><button onClick={reset}>Try Again</button></div>
}
// app/layout.tsx or root component
import { ErrorBoundary } from 'react-error-boundary'
function ErrorFallback() {
return (
<div>
<h1>Something went wrong</h1>
<button onClick={() => window.location.reload()}>Refresh</button>
</div>
)
}
export default function RootLayout({ children }) {
return (
<html>
<body>
<ErrorBoundary FallbackComponent={ErrorFallback}>
{children}
</ErrorBoundary>
</body>
</html>
)
}