> ## Documentation Index
> Fetch the complete documentation index at: https://docs.orbit.devotel.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Troubleshoot the dashboard error fallback page

> How to read the dashboard's internal fallback page — the 'Something went wrong / Try again' wall, the 'A newer version is available' reload wall, and the neutral 'Getting the latest version' spinner — which of three states you are seeing, what support needs to identify it, and how to validate it never loops on your deployment.

# 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:

1. **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.
2. **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.

The API error codes the page can surface are the curated, customer-safe
messages from the error envelope — for example `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:

1. **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.
2. **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.
3. **The route you were on** and what you clicked last. The boundary tags each
   captured error with the route and a `dashboard-route` boundary identity, so
   "the Contacts page after I opened a filter" is enough to localize it.
4. **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.

Send those through the dashboard's **Support** entry (left rail) or your usual
support channel. You will not escalate the stale-deployment class; the platform
deliberately does not page anyone on a reloadable old-tab failure, so do not
open a ticket for the reload wall unless it survives a reload.

## 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.ts`
  and `dashboard-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.

A fallback that persists after a reload — or one whose Error ID you can quote —
is a real bug; report it. A fallback that cleared on reload was the platform
working as designed.

## See also

* [Error codes reference](/reference/error-codes) — the curated message codes
  the generic wall can surface
* [Troubleshooting hub](/reference/troubleshooting-hub) — pick the runbook that
  matches the class you hit
* [Rate limits](/troubleshooting/rate-limits) — the `429` cousin of the
  generic retry wall: also transient and safe to retry
* [Tenant schema incomplete](/troubleshooting/tenant-schema-incomplete-503) —
  a 503 the dashboard can render as its fallback during a migration window
