# Plan 21-01 Summary: Error Boundary & Toast Notifications ## Result: COMPLETE **Duration:** ~3 min **Commits:** 2 ## What was done 1. **Created ErrorBoundary component** (`packages/web/src/components/ErrorBoundary.tsx`) - React class component with `getDerivedStateFromError` and `componentDidCatch` - Renders centered error card: red AlertCircle icon, "Something went wrong" heading, error message in muted text, Reload button - Styled with existing Tailwind classes matching the app's error state patterns 2. **Created Sonner toast wrapper** (`packages/web/src/components/ui/sonner.tsx`) - Thin wrapper exporting `Toaster` component from sonner - Configured with `position="bottom-right"` and `richColors` 3. **Wired into root route** (`packages/web/src/routes/__root.tsx`) - `` wraps `` inside AppLayout so route-level render errors are caught without destroying the nav shell - `` rendered as sibling to AppLayout for app-wide toast availability - `notFoundComponent` updated with "Back to Dashboard" Button/Link pointing to /initiatives 4. **Wired toast notifications into all mutation flows** - `SpawnArchitectDropdown.tsx`: `toast.success("Architect spawned")` on success, `toast.error("Failed to spawn architect")` on error - `ActionMenu.tsx`: `toast.success("Initiative archived")` on success, `toast.error("Failed to archive initiative")` on error - `CreateInitiativeDialog.tsx`: `toast.success("Initiative created")` on success (inline error kept for form validation) - `inbox.tsx`: `toast.success`/`toast.error` for both `resumeAgent` and `respondToMessage` mutations ## Decisions - 21-01: ErrorBoundary wraps Outlet only (not entire AppLayout) so nav shell survives render errors - 21-01: Toaster outside AppLayout as sibling — available even if layout breaks - 21-01: notFoundComponent uses shadcn Button with asChild + Link (consistent with component library) - 21-01: CreateInitiativeDialog keeps inline form error in addition to toast (inline error shows specific validation message) - 21-01: One success and one error toast per mutation — no toasts for query failures (those have inline error states) ## Verification - [x] `npx tsc --noEmit -p packages/web/tsconfig.app.json` — passes - [x] `npm run --workspace=packages/web build` — succeeds - [x] ErrorBoundary component exists and is wired into root route - [x] Toaster component rendered in root route - [x] All mutation callbacks use toast instead of (or in addition to) console.error