Error Flow
An error flow maps what happens when things go wrong: every way a task can fail, and the route from each failure back to progress. The happy path is one line; the error flow is the tree around it. Near-synonyms: unhappy path, failure path, exception flow, edge-case map.
Division of labor: Feedback, Loading, Errors & Recovery holds the message anatomy (what happened → why → what to do next, tone, placement) and the recovery patterns (undo, optimistic-UI rollback, offline). This file maps the ROUTES — which failures exist, where each one lands the user, and where they go from there. Write the flow with this file; write the words with that one.
When to use one
Before wireframes, for any flow involving input, money, network, files, permissions, or another party — which is to say, almost any flow. The error flow is the designer's pre-mortem: list every way the task can fail BEFORE drawing the screens, so recovery is designed into the layout instead of bolted onto a toast. It is also the cheapest usability review you can run on an existing product: walk the flow, force each failure, see where you land.
What it answers
- What can go wrong at each step? (Enumerated, not "handle errors.")
- Who caused it — user, system, network, or a third party — because the cause determines the tone and the fix.
- Where does the user land, and what's their next step from there?
- What survives the failure? (Typed text, chosen files, cart contents, scroll position.)
Failure taxonomy — different causes, different routes
- User mistakes (typos, wrong format, skipped field): catch at the field, inline, at the moment of completion; the route is "fix and continue," never "start over." Field-level evidence: Forms & Input.
- Validation / business-rule failures (username taken, date in the past, over quota): the input is well-formed but disallowed — say the rule and offer the nearest allowed alternative.
- System failures (server error, crash, feature down): not the user's fault; apologize once, preserve work, give retry + a status route (Feedback, Loading, Errors & Recovery covers status pages).
- Network failures (timeout, drop, offline): often transient — queue and auto-retry where safe, then surface; distinguish "you're offline" from "we're down," because the user's fix differs.
- Permission failures (not allowed, wrong tier, expired session): route to the grant path — request access, upgrade, or re-auth with work preserved. Full mapping: Permission Flow.
- Payment failures (decline, expired card, 3-D Secure abandoned, fraud hold): the highest-stakes branch; keep the cart, name the fix ("try another card"), never blame, and don't leak fraud logic.
- Upload/file failures (too large, wrong type, corrupt, virus flag): state the constraint BEFORE selection where possible, and the specific violated constraint after.
The recovery-first rule
Every error path ends in a next step — retry, fix, alternative route, or a named human — never a dead end. Test: for each error node in your flow, follow its outgoing arrow. No arrow = unfinished design. "OK" buttons that dismiss the error and return the user to the same broken state fail this test; so do support links with no error reference attached.
Example — Upload File
Choose File ──▶ Validate ──ok──▶ Upload ──▶ Done
│
│ file too large
▼
Clear Error + Max Size Shown
("PDFs up to 25 MB — this file is 40 MB")
├──▶ Choose New File ──▶ Validate (loop)
├──▶ Compress/Split help link ──▶ back to Choose
└──▶ Cancel ──▶ previous screen, nothing lost
Upload ──network drop──▶ Auto-retry ×3 ──▶ still failing
├──▶ Manual Retry (file kept)
└──▶ Save as pending; upload
when back online
Failure branches to note: validation happens before the expensive step; the error states the limit AND the file's actual size; three exits, all forward or safely back; the network branch retries silently before bothering the user; nothing ever discards the chosen file.
Common mistakes
- One generic error screen for every cause ("Something went wrong").
- Dead ends: error → dismiss → same state, no route changed.
- Losing work on failure — the most rage-inducing pattern there is.
- Designing errors after the screens, so recovery has no room in the layout (no space for inline messages, no place for a retry).
- Retry loops with no cap and no escalation to a human.
- Treating all errors as equally rare; instrument them — your most common real state may be an error you spent an hour on.
Checklist
- Every step in the main flow has its failure modes listed — before wireframes (the pre-mortem).
- Each failure is classified (user / validation / system / network / permission / payment / file) and routed accordingly.
- Every error node has at least one outgoing arrow; no dead ends.
- User work is preserved across every failure branch.
- Retries are capped and escalate to an alternative or a human, with an error reference attached.
- Messages follow the anatomy in Feedback, Loading, Errors & Recovery and the copy guidance in UX Writing & Microcopy.
- Preventable errors are prevented (constraints shown up front, formats accepted liberally) rather than caught.
- Error-caused empty states route per Empty State Flow; component-level error states appear in the State Flow diagram for that component.
Sources
- Nielsen Norman Group — "Error-Message Guidelines"; "10 Design Guidelines for Reporting Errors in Forms"; "Hostile Patterns in Error Messages"; heuristic #9, "Help Users Recognize, Diagnose, and Recover from Errors" (nngroup.com).
- Hurff, S. (2016). Designing Products People Love. O'Reilly, ch. 6 — the error state as one of the UI Stack's five states every screen must design.
- Message anatomy, undo/rollback, offline, and status-page practice: Feedback, Loading, Errors & Recovery and its sources (Nielsen 1993; WCAG 2.2; Egelman et al. 2008).