install
source · Clone the upstream repo
git clone https://github.com/Intense-Visions/harness-engineering
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/Intense-Visions/harness-engineering "$T" && mkdir -p ~/.claude/skills && cp -r "$T/agents/skills/claude-code/next-error-boundaries" ~/.claude/skills/intense-visions-harness-engineering-next-error-boundaries-62ffd8 && rm -rf "$T"
manifest:
agents/skills/claude-code/next-error-boundaries/SKILL.mdsource content
Next.js Error Boundaries
Handle runtime errors and missing routes gracefully with error.tsx and not-found.tsx
When to Use
- Displaying a user-friendly error UI when a route segment throws during rendering or data fetching
- Providing a recovery mechanism (retry button) without reloading the entire page
- Customizing the 404 page for missing routes or resources
- Isolating errors so one failing segment does not crash the entire application
- Handling global uncaught errors at the root layout level
Instructions
- Create
in a route segment directory to catch errors thrown by that segment'serror.tsx
or its Server Components.page.tsx - Mark
as a Client Component witherror.tsx
— error boundaries must be Client Components.'use client' - Accept
anderror: Error & { digest?: string }
props —reset: () => void
is a server-side error ID for log correlation;digest
re-renders the segment.reset - Create
inglobal-error.tsx
to catch errors from the root layout — it replaces the entire layout includingapp/
and<html>
, so include them.<body> - Call
fromnotFound()
inside any Server Component to trigger the nearestnext/navigation
.not-found.tsx - Create
innot-found.tsx
for a global 404 page, or in any route segment for segment-specific 404s.app/ - Nest
closer to the throwing component to limit the error UI scope — a top-levelerror.tsx
catches all descendant errors but shows a large recovery region.error.tsx - Log the
to your error monitoring service (Sentry, Datadog) to correlate client-visible errors with server logs.error.digest
// app/dashboard/error.tsx — segment error boundary 'use client'; export default function DashboardError({ error, reset, }: { error: Error & { digest?: string }; reset: () => void; }) { return ( <div role="alert"> <h2>Something went wrong loading the dashboard</h2> <p className="text-sm text-gray-500">Error ID: {error.digest}</p> <button onClick={reset}>Try again</button> </div> ); } // app/posts/[slug]/not-found.tsx — segment-specific 404 export default function PostNotFound() { return ( <div> <h1>Post not found</h1> <p>The post you are looking for does not exist or has been removed.</p> </div> ); } // app/posts/[slug]/page.tsx — triggering not-found import { notFound } from 'next/navigation'; export default async function PostPage({ params }: { params: { slug: string } }) { const post = await fetchPost(params.slug); if (!post) notFound(); // triggers not-found.tsx return <article>{post.content}</article>; }
Details
Next.js automatically wraps each route segment in a React error boundary when
error.tsx exists. The error boundary catches errors thrown during rendering, in event handlers, or in asynchronous data fetching within that segment.
Error propagation: Errors bubble up through React's component tree until they reach an error boundary. Without
error.tsx, unhandled errors propagate to the root and show the default Next.js error page (development) or a blank white screen (production).
function: Calling reset()
reset() attempts to re-render the content within the error boundary. If the underlying error was transient (e.g., a network blip), the reset succeeds. If the error persists, the error boundary catches it again. Combine with a retry counter to avoid infinite loops.
vs global-error.tsx
: error.tsx
error.tsx in app/ catches errors from the root page but not from the root layout. global-error.tsx catches errors from the root layout itself (e.g., a broken navigation component). global-error.tsx must render <html> and <body> because it replaces the entire document.
Server vs client error messages: In production, error messages thrown on the server are not forwarded to the client to avoid leaking sensitive details. Only the
digest ID is passed. In development, full error details are shown. This asymmetry is intentional — use the digest to look up errors in server logs.
not-found.tsx placement: A
not-found.tsx in a segment catches notFound() calls from that segment only. A not-found.tsx in app/ serves as the global 404 fallback for all routes.
Source
https://nextjs.org/docs/app/building-your-application/routing/error-handling
Process
- Read the instructions and examples in this document.
- Apply the patterns to your implementation, adapting to your specific context.
- Verify your implementation against the details and edge cases listed above.
Harness Integration
- Type: knowledge — this skill is a reference document, not a procedural workflow.
- No tools or state — consumed as context by other skills and agents.
Success Criteria
- The patterns described in this document are applied correctly in the implementation.
- Edge cases and anti-patterns listed in this document are avoided.