Troubleshoot the dashboard error fallback page
When a dashboard page crashes at render instead of loading cleanly, Orbit does not leave you on a blank frame or a dead browser error. Every dashboard route sits behind a React error boundary that renders one of three surfaces — a retry wall, a reload wall, or a brief neutral spinner — and reports the failure to the platform’s observability pipeline in the background. This page decodes each surface so you can tell support exactly which one you hit and what it means.Why the fallback exists
Dashboard pages are rendered in the browser. Any page — a widget that mis-assembles, a render crash, a chunk that 404s mid-deploy — can throw during that render. Each route is wrapped in a boundary whose only job is to catch the throw, choose the recovery surface below, and report it. The boundary is deliberately thin: it cannot keep the failed page on screen, but it always offers a way out (Try again, Reload, or Back to Dashboard) and never loses the error silently. Two controls inside the boundary are worth understanding up front, because most fallback reports are answered by one of them:- The missing-middleware guard. Some requests reach the dashboard shell without the auth middleware ever running for them — a crawler probe for an asset-shaped path, or a page that references a broken asset URL the router matches as a route. The dashboard layout guards its session check for exactly this class and redirects the request to the sign-in page instead of throwing; the guard is covered by a regression test shipped with the app, so the fallback page is almost never what those probes should see. If you see the fallback after following a broken link, note the link — that is the signal.
- The stale-deployment classifier. A tab open across a release can fail its next request because the new build replaced hashed assets the old page still needs. That class is recoverable by reload, so the boundary detects it and routes to the reload surface below instead of the generic retry wall.
When the fallback kicks in
The boundary picks exactly one surface per crash:- “Getting the latest version” (spinner) — the failure looked like a chunk or dynamic-import blip during the page’s first load. The page reloads itself once, automatically; a manual Reload stays on screen in case the navigation stalls. You should not have to act at all.
- “A newer version is available” (reload wall) — the crash matched the stale-deployment class: your tab is running an older build and the freshest assets are one full reload away. Click Reload once. The boundary stamps a one-shot marker on the reload, so it cannot loop — if the failure persists after one reload, the next visit shows the honest generic wall instead.
- “Something went wrong” (generic retry wall) — anything that is not the stale class and not a connectivity problem: a render crash, a widget that mis-assembled, a server-side fault rethrown past the layout guard. The page offers Try again (re-renders the failed segment without a full reload) and Back to Dashboard.
- “Connection problem” — a header variant of the generic wall. When the failure was a transport error (offline, DNS, a dropped socket) the header says so and the body already tells you to check the connection; a completed 4xx/5xx from the server still gets the generic header, so a library-level “connection problem” title is never confused with a genuine server crash.
INSUFFICIENT_BALANCE,
RATE_LIMITED, or TELNYX_ERROR-class provider codes — passed through the
page’s redactor. Raw provider text, generic INTERNAL_ERROR placeholders, and
bare HTTP <status> strings are suppressed in production; what you see is the
actionable message or the generic fallback, never a leaked provider fragment.
What to capture when you report it
Support can identify the failure from four signals — collect as many as you can:- Which surface you saw: retry wall, reload wall, or the spinner. Each surface points at a different class; “Getting the latest version” and “A newer version is available” are usually benign and reload-recovered, while the generic wall is the one that warrants a report.
- The Error ID (digest) shown in monospace on the generic wall. Next.js attaches a digest to the caught error and the boundary renders it; quoting it lets support grep the exact event instead of the time window.
- The route you were on and what you clicked last. The boundary tags each
captured error with the route and a
dashboard-routeboundary identity, so “the Contacts page after I opened a filter” is enough to localize it. - The body text if the wall showed a specific message (for example
Insufficient balance) rather than the generic sentence — that message is already the curated API error, and a report quoting it answers itself.
Tenant-owned controls
The fallback surfaces behaviour you control — there is no platform-side switch for it and no promise that it cannot appear:- Keep sessions fresh. The “A newer version is available” wall is almost always a tab that lived across a release. Reloading is the whole fix; if an operation was mid-flow, complete or discard it before reloading if you can.
- Validate your deployment. Integrators embedding the dashboard can run the
app’s own layout-guard regression test
(
layout.clerk-middleware-missing-guard.source-pin.test.ts) alongside two dashboard source-pin suites (hub-primitives-adoption.source-pin.test.tsanddashboard-phantom-var-hex-fallback.source-pin.test.ts) to confirm the guard and the widget conventions are intact in their build. - Do not rewire the boundary. The recovery logic is shared and unit-tested; a deployment that replaces or deletes the boundary turns a one-reload-fix into an unrecoverable white screen.
See also
- Error codes reference — the curated message codes the generic wall can surface
- Troubleshooting hub — pick the runbook that matches the class you hit
- Rate limits — the
429cousin of the generic retry wall: also transient and safe to retry - Tenant schema incomplete — a 503 the dashboard can render as its fallback during a migration window