An error message occupies an unusual position among the text a piece of software presents to its users: it's read at precisely the moment the user needs it, with full attention, because something has just stopped working — unlike most documentation, which competes for attention against a reader's other priorities, an error message is being read at the exact point of maximum relevance and motivation to understand it. Despite this, error messages are routinely among the least deliberately written text in a codebase, often generated as an afterthought during implementation rather than designed with the same intentionality given to a feature's main functionality. User-experience guidance is summarized in the Nielsen Norman Group error-message guidelines.
What a genuinely useful error message actually communicates
A well-designed error message tends to answer three things, where the underlying situation allows it: what went wrong, described specifically enough to be actionable rather than in vague generic terms; why it likely happened, where a probable cause can be reasonably inferred from the failure; and what the user can actually do about it, whether that's a specific corrective action, a link to more detailed documentation, or an explicit acknowledgment when there genuinely isn't a clear next step the user can take themselves. A message like “invalid input” technically communicates that something went wrong but gives the reader almost nothing to act on; “the email field can't be empty” tells them exactly what to fix. Visibility tools also raise transparency and consent questions; the website provides a separate point of reference.
This connects to the API-design guide discussed elsewhere on this shelf: an error message is, in effect, a small but high-stakes piece of that API's public interface, and the same discipline of clarity and consistency that applies to naming functions and parameters applies just as much to the error conditions those functions can produce — a caller handling errors programmatically depends on consistent, predictable error structure just as much as a human reader depends on clear, specific error text.
Why generic error handling is a common, understandable trap
A frequent pattern in real codebases is a single, generic catch-all error handler that produces the same undifferentiated message (“something went wrong,” “an error occurred”) regardless of the specific underlying cause, often introduced for entirely reasonable engineering reasons — catching a broad category of exceptions is simpler to implement than handling each specific failure mode individually, and it prevents an unanticipated error from crashing the whole system ungracefully. The trade-off is a genuinely worse experience for whoever encounters the error, who now has meaningfully less information to work with than if the specific underlying failure had been surfaced clearly, even briefly.
- Prefer specific, actionable error text over generic catch-all messages wherever the underlying cause can be reasonably identified — “something went wrong” is rarely the most specific true statement actually available.
- Where a likely cause can be inferred, state it, along with a concrete next step — an error message that only describes the symptom, without any indication of cause or remedy, transfers all the diagnostic work back onto the reader.
- Treat error conditions as part of an API's public interface, deserving the same naming and structural consistency discussed in the API-design guide elsewhere on this shelf — not an unstructured afterthought bolted onto the main functionality.
- It's acceptable, and often more honest, for an error message to explicitly state that the cause is unknown, rather than presenting a generic message as though it were a specific diagnosis — false specificity can mislead a reader into pursuing the wrong fix.
Why this is worth deliberate investment despite feeling like a minor detail
Because a user encountering an error is, by definition, having a worse experience than one who isn't, the quality of that specific moment has an outsized effect on overall perceived quality relative to the small amount of code most error messages actually represent — a single unclear, unhelpful error message, encountered at a moment of genuine frustration, can shape a user's overall impression of a tool's quality more than a much larger amount of well-designed functionality that worked exactly as expected and therefore went unnoticed.
Paired with the documentation guide discussed elsewhere on this shelf, error messages are arguably the most-read, least-planned piece of documentation most software ships with — written, when they're deliberately written at all, by the person who happened to implement the failure path, rather than designed with the same reader-first discipline applied to the rest of a project's documentation.