Skip to main content

Dashboard fallback guards

The dashboard ships a set of defensive fallbacks — designed degraded states that keep a page usable when one part cannot render its full content. Each fallback is covered by an automated spot-check that fails the build if the guard is ever removed. This page is the operator walkthrough: read it top to bottom once, then use the decision tree at the end when a live incident lands on your desk. Every section quotes the guard’s actual rendered text, tells you how to confirm what you are seeing, and names the first action to take.

1. Where the fallbacks surface

Four areas of the dashboard carry guarded degraded states:
  1. The Home page (/home) — the banner widgets below the greeting (balance, trial-number promotion, KYC reminder, getting-started checklist, fraud alerts) each render a height-matched placeholder the moment the page first paints, so the widget swaps into its reserved space without moving anything on screen. If the whole page fails to load, a full error panel replaces it with a Try again control and an error ID.
  2. Hub pages — Messages, Campaigns, Contacts, and Reports all render their header and their empty/zero states through the same shared components, so a hub with no traffic shows the same guided empty state rather than a blank panel.
  3. List footers — every cursor-paged list across the dashboard renders the same Load more button label in exactly one casing, so the pager reads identically on every surface.
  4. The session layer — a session check that cannot complete degrades to a clean redirect to your sign-in page instead of an unhandled error.

2. The full-page error panel contract

When an entire page — Home or any other dashboard route — fails to render, the error boundary replaces the page with one panel. Before you escalate, read the panel carefully, because it already tells you which of three modes you are in: Mode A — a genuine crash. The panel reads:
Something went wrong An unexpected error occurred Error ID: 8bff7a2d… Try again · Back to home
The Error ID is the crash’s digest. Quote it verbatim in your ticket — support routes the ticket by that ID to the cluster that produced it. Press Try again first; a persistent failure after retry warrants the ticket. Mode B — a newer version of the dashboard. The panel reads:
A newer version is available This page was updated while it was open. Reload to get the latest version and continue. Reload · Back to home
This is not a bug. A deploy landed while you had the page open; the button on screen is Reload, not Try again, and one reload clears it. If the same wall comes back immediately after the reload, it is persistent — treat it as mode A and open a ticket. Mode C — a network problem between you and the platform. The panel reads:
Connection problem Couldn’t reach the server. Check your internet connection and try again. Try again · Back to home
No error ID is printed in this mode because the request never reached the server. Check the device itself (VPN, corporate proxy, captive portal) before filing. The contract the guard holds, whichever mode is on screen: the panel gives you a Try again (or Reload) control, never leaves you on a dead page, and prints the error ID whenever the platform can see the error. A panel missing any one of those is itself reportable.

3. The sign-in bounce guard — walkthrough

The session-check guard exists for one shape of failure: the dashboard’s sign-in handshake cannot complete because of an authentication misconfiguration (the session cookie the browser sent is already dead, the auth provider cannot be reached, or a custom SSO flow returned an empty session). Throwing an error would leave you on a dead page; instead the guard redirects you cleanly to your sign-in page for your locale — a loop-free target. Every other failure class still surfaces through the standard error boundary, so a real fault is never silently swallowed. When you land on this guard, work through it in this order:
  1. Sign in once more. A one-shot bounce after a long idle, an expired session, or a browser restart is the guard doing its job. Re-login completes cleanly and you are done.
  2. Check your side first. If every sign-in redirects again immediately, ask: did anything in your organization’s sign-in path change in the last 24 hours? Workspace-owned misconfigurations come first — a custom SSO / identity-provider integration you set up yourself, a custom domain pointing at your branded sign-in, a VPN or content-filter that blocks the auth provider’s host, or a browser extension stripping third-party cookies. Switch to a clean browser profile or another network to test; if the loop stops, the cause is in your environment and it is yours to fix.
  3. Then suspect the platform. If the loop recurs on a clean browser, on a fresh device, and for every teammate in your organization, file a ticket. Say exactly what the loop is doing: “sign-in → redirect to /home → immediate bounce back to /en/login”, note the locale, and quote the URL the browser lands on. A platform-side session defect always recurs for every seat in the workspace; a session defect that affects one seat only is nearly always local.
One more guardshape to expect: after the re-login you may briefly see a “Getting the latest version” state while the tab re-bootstraps. That is the full-page error panel in its auto-recovery posture, and it resolves itself — do not act on it.

4. The hub empty-state explorer

The shared hub pages — Messages, Campaigns, Contacts, Reports — all route their zero-traffic state through the same empty-state primitive. When you open one with no data, the page does not show a blank panel; it shows a designed empty state whose job is to tell you the hub is healthy and what your first action on it is. An empty state by itself is never a bug. What it looks like per hub: Two distinct states share the surface — read the heading before you act:
  1. Zero-traffic state — “No X yet.” The workspace genuinely holds nothing; the empty state is the destination, and the first action it offers is the way out.
  2. Filtered-zero state — “No results match your filters.” The workspace does have rows but the current search or filter returned none. The empty state offers Clear filters instead of a create action, and a line names the active filter count. If a list appears to be missing rows you know exist, look for the active-filter indicator first.
Two failure modes are reportable. An empty state that shows no first action at all (no button, no link, no guidance — a naked “No X yet”) has lost its contract: the guard exists precisely to keep every hub’s empty state actionable. And a hub that renders literally nothing — blank white where the header and empty state belong — is a broken render, not an empty state; file it as a defect with the URL.

5. Pager normalization — what “Load more” should look like

Every cursor-paged list across the dashboard — contact lists, conversation lists, message history, reports — draws its pager footer through the same label. Two properties are locked in:
  • One label, one casing. The button reads exactly Load more, sentence case, on every list. Previously a handful of surfaces rendered “Load More” while the rest rendered “Load more” — the same control reading differently depending on which page you were on. The guard now enforces the single casing.
  • One behavior. Pressing it appends the next page to the list; the button shows a “Loading…” state while the page loads, and disappears when the list runs out.
Report a divergence, not a design choice. If you find a list that says “Load more” on one console and “Load More” (or “Show more”, “Next page”) on another, that is the regression the guard exists to catch — file it with both URLs. If a list’s pager is missing entirely while the data clearly continues (say, a 500-row contacts list ends at row 25 with no button), that is the same class.

6. The theme-token guarantee — workspace vs. platform

A color fallback is a hard-coded color painted when a named theme token does not exist. The dashboard historically had a class of these — a heading or badge in a hard blue, a card border in a hard gray — that never adapted to dark mode and never re-tinted when your organization set a primary color. The guard now rejects any new hard-coded color at build time, so every paint you see resolves through a real theme token. When a color looks wrong, run this check in the branding console before you file:
  1. Open Settings → Branding in your workspace and read your Primary color and Accent color fields. If either is set, your organization has a theme override — the color you are seeing is almost certainly yours, not the platform’s. Use the per-field Revert on the suspicious field, or Reset to defaults (with the confirmation step) to clear the whole set, then reload. The branding console walkthrough documents every field on the page and the resolver cache (your revert can take up to ~60 seconds to reach public surfaces).
  2. With the workspace override cleared, flip the dashboard between light and dark mode. A correctly themed element re-paints with the theme. An element that stays one color across both modes — or a color that visibly belongs to neither your brand palette nor the neutral default theme — is a platform-side fallback and reportable.
Quote the page, the element, and which mode it fails in (“the chart accent stays cyan in dark mode with no workspace override set”). If you resell the dashboard to subaccounts, also check the per-subaccount override path before filing: a subaccount that inherits your parent branding can appear to show “platform wrong colors” that are actually your own.

7. Bug or workspace misconfiguration — the triage decision tree

Match the symptom to its owner before you act:
  • A full-page error panel → read which of the three modes (section 2). A newer version is expected, reload and walk away. Connection problem is your network until proven otherwise. Something went wrong with an error ID that survives a Try again is platform-owned — ticket with the ID.
  • Bounce to sign-in
    • single bounce after idle → expected; re-login.
    • loop on your browser only → workspace-owned environment (extensions, VPN, cookies); test a clean profile.
    • loop for every seat in the organization → platform-owned; ticket with the redirect path and locale.
  • A hub shows an empty state
    • “No X yet” → zero-traffic by design; take the first action the state offers.
    • “No results match your filters” → filtered-zero; Clear filters.
    • empty state with no action offered, or a hub that renders nothing at all → platform-owned; ticket with the URL.
  • The pager reads differently on two consoles (“Load more” vs. any other casing or wording) → platform-owned; ticket with both URLs.
  • An off-theme color
    • clearing your workspace branding override (section 6) fixes it → workspace-owned.
    • it survives a reset-to-defaults and ignores light/dark → platform-owned; ticket with page, element, and mode.
  • Workspace-owned (fix it in your settings): custom theme overrides under white-label branding; a sign-in flow you configured yourself (custom SSO) that reproduces on demand; empty states that resolve as soon as the surface has data.
  • Platform-owned (open a support ticket): Home page layout shifts as its banner widgets arrive; a hub header or empty state that renders nothing at all; a pager label that differs across two consoles; a session redirect loop that recurs after one re-login on a clean browser; an off-theme color in the default theme. Quote the error ID printed next to any error panel — the ID routes the ticket to the right cluster.

See also