Design the broken states first
Most interface work starts with the happy path, because the happy path is the thing that is easy to imagine and pleasant to draw. The empty, loading, partial, offline, denied and failed states arrive later, if there is time, which there rarely is.
I have started working the other way round. I design the failure states before the success state, and it has made my work better in a way I did not expect: it changes the success state too, because the happy path stops being able to quietly assume things that are not true.
A checkout that looks superb until a card is declined is not a finished checkout. It is a demo. And the declined card is not a rare edge case, it is a routine event happening to a person at the exact moment they have decided to trust you with money.
The states where a product is most likely to lose somebody are precisely the states we design last, on the least budget, with the least attention. That is backwards, and the fix is mostly a matter of sequence.
The failure states are a specification
When you design the error case first you are forced to ask what can actually go wrong here, and that question interrogates the happy path harder than any critique will. On a mortgage application I worked on, listing the failure modes surfaced that a third of applicants would need a document they did not have to hand. That single realisation restructured the entire flow, because we could sequence around it instead of dead-ending into it.
Had I drawn the happy path first, I would have produced a beautiful uninterrupted sequence that only worked for people who happened to have their last two payslips on the desk.
The states worth enumerating
- Empty, because there is nothing yet, which is every user first experience
- Empty, because a filter excluded everything, which is a different problem needing a different answer
- Loading, split into fast enough to ignore and long enough to explain
- Partial, where some data arrived and some did not, the most commonly skipped state of all
- Failed, with a specific cause and a stated recovery path
- Denied, where the user lacks permission and needs to know who to ask
- Stale, where what is on screen is real but no longer current
- Offline, where the action is queued rather than lost
Not every screen needs all eight. Most need more than the one they get.
Write the message before you draw the screen
Error copy written after the layout is finished ends up compressed into whatever room is left, which is how we get something went wrong. Write the sentence first and the layout accommodates it.
A good failure message does three things: it names what happened in the user's terms rather than the system's terms, it says whether their work is safe, and it gives one specific next action. That second one gets forgotten most often and is worried about most.
Something went wrong is not an error message. It is an apology from a system that did not want to explain itself.
What changes in practice
Two things, immediately. Engineering estimates get more honest, because the states that usually surface halfway through a sprint are on the table at the start. And critique gets better, because the conversation is about behaviour and edge cases rather than about spacing.
The third change takes longer to notice. You start designing systems that degrade gracefully rather than systems that are either perfect or broken, and users trust the degraded version far more than they trust the perfect one, because they have seen it hold up when something went wrong.