A useful error message explains the known problem and the next action without discarding the user’s work. Put field errors beside the relevant input and provide a navigable summary when appropriate. Treat a confirmed rejection differently from a request whose result is still unknown.
Start with the failed task
Consider a free workshop booking form with a selected session, name, and email address. The visitor presses “Reserve my place.” Several things can happen: an address is missing, the session has filled, the service is unavailable, or the connection drops after a reservation may already have been saved.
This worked redesign follows those four paths. They all need a message, but they do not share the same recovery. “Something went wrong. Try again” makes the user diagnose the system and may encourage another submission when the first one already succeeded.
Write from the result the system actually knows. A rejected email format is a known input problem. A timeout is missing confirmation, not proof that nothing happened. The wording and button must reflect that distinction.
Use GOV.UK’s error summary as a concrete reference
The GOV.UK Design System shows validation errors in a summary at the top and beside the affected answers. Its summary links to those fields, uses matching error wording, and receives keyboard focus after submission. This creates a navigable repair path rather than simply adding red text.
For the workshop form, a missing email can therefore appear in both places as “Enter your email address.” Selecting the summary link takes the visitor to that input. Their session and name remain filled in. The implementation should associate the field with its error so assistive technology can identify the problem.
This reference describes the GOV.UK form pattern, not a rule that every small inline interaction must reproduce the whole component. The transferable decision is to make the problem discoverable and connect it to the place where it can be fixed.
| Weak message | Worked replacement | Placement and recovery |
|---|---|---|
| Invalid input | Enter your email address. | Summary and email field; retain the other answers |
| Bad email | Enter an email address in the format name@example.com. | Email field; allow correction rather than clearing it |
| Unavailable | The afternoon session is full. Choose another available session. | Near session choice and in the submit result; keep name and email |
| Error 500 | We could not load available sessions. Try loading them again. | Availability panel; Retry performs a read, not a new booking |
Preserve the work around the error
When validation fails, keep entered values. Do not force the visitor to retype their name because the email was missing. Show the error after the relevant validation event; avoid announcing invalidity before a person has had a reasonable chance to finish entering an answer.
If a selected session becomes full, preserve the selection as unavailable long enough to explain what changed. Present the remaining options and let the person choose. Silently switching them to the morning session would create a different booking from the one they requested.
An error can also be non-editable. If session data cannot load, there is no useful field for the visitor to “correct.” Keep the problem at the page or component level and offer the operation that can recover it. Technical diagnostic details belong in logs with a support reference if needed, not in the primary instructions.
Handle an unknown submission without inventing an outcome
Suppose the reservation reaches the server, but the response never reaches the browser. The interface cannot truthfully display either “Reserved” or “No reservation was made” until it checks the existing request. The design needs a pending or uncertain state, not merely a better error adjective.
For this flow, give each submission a stable request identity. “Check reservation status” asks about that request; it does not create another reservation. If the server confirms success, show the reference and session. If it confirms rejection, show the relevant recovery. If it remains unresolved, keep that uncertainty visible and provide a support route.
The copy is a contract with the implementation. A status button is misleading if it simply posts the same booking as a new request. Agree the underlying behavior with engineering before handing over the screen.
| Known state | Message | Action and expected behavior |
|---|---|---|
| Reservation confirmed | Your place is reserved for Saturday afternoon. Reference: [reference]. | View reservation; show the persisted record |
| Capacity rejection confirmed | The afternoon session is full. No place was reserved in that session. | Choose another session; preserve contact details |
| Result unknown after timeout | We have not confirmed your reservation yet. Check its status before submitting again. | Check reservation status; look up the existing request |
| Still unresolved | We still cannot confirm the result. Keep this request reference if you contact support. | Check again or contact support; do not claim failure or success |
Make the repair path work with keyboard and assistive technology
After a submitted form returns validation errors, move focus to the summary in this design. Its links should move to the relevant controls, not just scroll vaguely toward a section. Keep focus visible and preserve the normal reading order.
Associate each inline message with its input, and use text as well as color to identify the problem. A red border alone says neither what happened nor how to fix it. For a changing request status, make the update available to assistive technology without repeatedly stealing focus from the person’s current task.
W3C’s status-message guidance explains why dynamically displayed results may need programmatic exposure even when focus does not move. Test the actual flow with the assistive technology you support. Adding an alert to every keystroke can create a noisy form rather than an accessible one.
Use an acceptance table before calling the copy finished
Run each scenario from input to recovery. Record both the visible message and the resulting data state. A clear sentence attached to an action that loses input is still a failed recovery design.
For the uncertain-submission case, test both outcomes: the first request was committed, and the first request was rejected. Confirm that checking status reaches the correct result without creating a second reservation. A single successful-network demonstration cannot verify this branch.
Use this small writing template for future messages: condition we know; consequence for the user’s task; exact message; available action; preserved work; next state. If one field is unknown, resolve the behavior before making the wording sound more confident.
| Scenario | Expected visible behavior | Expected data behavior |
|---|---|---|
| Email missing | Summary links to email; message names missing value | Session and name retained; no reservation created |
| Session filled during completion | Current availability explained; alternatives shown | No overbooking; no silent session substitution |
| Availability request fails | Page-level retry; form context retained | Retry reads availability only |
| Response lost after commit | Uncertain state, then confirmed result on lookup | One reservation for the original request |
| Response lost after rejection | Uncertain state, then rejection on lookup | No reservation; correction remains possible |
| Keyboard-only repair | Summary, field, and submit reachable with visible focus | No input lost while navigating |
