Skip to main content
Exemplar page — first pass. This is a proposal for review, not established policy. It is also a proposal for how to improvise a failed state at all — not a claim that Titan already has one. Checked directly against source: TITAN-GAP-22 — no component in Titan expresses a failed action today. There is a loading state and a disabled state, and nothing between them for failure, and no token names a control-level error state. Every product surface currently improvises this — inline text, a toast, a banner, or nothing — and what follows is a proposal for improvising it consistently, not a description of an existing primitive.
This page covers deterministic failures only — a failed API call, a failed save, a page that couldn’t load. Where the “failure” is a wrong-but-confident model output rather than an exception, see AI Experience overview, which defines a richer outcome-state model (working, streaming, confident-and-wrong, degraded, and more) for anything model-backed. Nothing on this page applies to that case.

The problem

An action or a load can fail for reasons that have nothing to do with the reader — a network blip, a downstream service down, a permission that changed underneath them. Without a consistent answer for where that failure shows up, every team invents its own: an inline message here, a toast there, a full-page blank somewhere else, and occasionally nothing at all, which is the worst of the four because the reader cannot tell a failure from success. Where a failure shows matters as much as whether it shows. A message far from the control that triggered it makes the reader hunt for what it’s about. A toast that vanishes in five seconds gives someone reading slowly nothing to act on. A dialog that closes on failure discards the one piece of context the reader needs to know whether their input survived. This pattern is not the Alert or the Toast. The pattern is deciding, for a given failure, which of Titan’s feedback components is the right place to show it, and what happens next.

Deciding where a failure shows

When this applies

  • An action the reader took — save, submit, delete, export — did not complete successfully.
  • A load — a page, a table, a panel — failed to retrieve what it needed, in whole or in part.
  • The failure is deterministic: an exception, a rejected request, a timeout. There is a definite thing that went wrong, not a model output that might be wrong.

When it doesn’t

Structure

Behavior

Constraints

Content

Sentence case, no exclamation marks, and a stated next step in every message — see Error messages, which this page follows rather than restates.

Accessibility

  • An Alert that appears after page load carries a live-region role so a screen reader user hears it — see TITAN-ALR-08.
  • Severity is carried by the icon and the words, not only by color — see TITAN-ALR-09.
  • A control’s loading state during a retry sets aria-busy="true" automatically — see Button — but the failure message that follows is a separate announcement the composition still has to make.
  • A full-page error state should move focus to its heading once it replaces a loading region, so a screen reader user lands on the result rather than on a control that no longer has anything to act on.

Variations

Anti-patterns

A toast with no path to retry or recover. A transient notification that vanishes in five seconds is the wrong place for a failure the reader is expected to act on — there is nothing left on screen once it’s gone. Closing a dialog on failure. The reader is left unable to tell whether their input survived, and has to redo work that may already have gone through. See TITAN-DESTROY-09. Silent, unbounded automatic retry. A request that keeps failing quietly in the background never gives the reader a signal that something is actually wrong, and never hands them a way to stop waiting. A disabled control as the only sign that something failed. Indistinguishable from “you don’t have permission,” “select a row first,” or a bug — three different messages that all render identically with nothing said.
Last modified on September 2, 2026