Error Message Craft
Parent: Writing and Documentation · researched 2026-05-29T18:25:36.049Z· 17 sources · 10 concepts · skill error-message-craft
Error messages are the most-read text most software ever produces. They are also the worst-edited. The goal: tell the user what went wrong, why it went wrong, and what to do next.
Overview
- Error messages are the most-read text most software ever produces. They are also the worst-edited. The goal: tell the user what went wrong, why it went wrong, and what to do next. [source]
1. The "what / why / what to do next" triple
- What went wrong - the observable failure, stated in user terms. [source]
- Why it went wrong - only when the cause helps the user decide what to do. [source]
- What to do next - a concrete action. [source]
- The triple does not have to be three separate sentences. For a short field validation: [source]
- > "Email must include an @ symbol." [source]
- > "We couldn't save your changes (database unreachable). Wait 30 seconds and retry; if this persists, contact support with request ID req_abc123." [source]
2. No-blame language — the system owns the failure
- Three substitutions do most of the no-blame work: [source]
- "You [did wrong thing]" → "[Field] requires [thing]" [source]
- "You failed to..." → "[Action] needs..." [source]
- "Invalid input" → "[Field name] must be [format]" [source]
- Test: replace "you" with "the system" in the draft. If the sentence now reads as the system admitting a defect, the original was probably user-friendly. If it reads as nonsense, the original was blame language. [source]
3. State the problem in user terms, not internal terms
4. Error codes — naming conventions
5. Provide a concrete next action, or admit you cannot
- A complete next-action clause names one of: [source]
- A retry hint with a time bound: "Try again in 30 seconds." Not "try again later." [source]
- A specific input fix: "Add an @ symbol to your email." [source]
- An escalation path with diagnostic info: "Contact support and include request ID req_abc123." [source]
6. Conservative punctuation
7. i18n considerations
- Avoid contractions where translation may be awkward ("can't" → "cannot"). [source]
- Avoid idioms ("hit a snag", "ran into a wall"). They do not translate. [source]
- Avoid concatenation in code ("Error: " + fieldName + " is invalid"). Breaks grammatical agreement in gendered languages. [source]
- Plan for pluralization complexity. Use ICU MessageFormat or equivalent. [source]
8. NN/g hostile patterns — what never to ship
- Mockery: "Oops! Something went terribly wrong! 😱" [source]
- Self-deprecation: "Our bad! We messed up." [source]
- Vague hedging: "An unexpected error occurred." [source]
- Exposed internals: stack traces, internal class names, raw DB errors. [source]
- Marketing voice in failure: "Thanks for your patience as we work to deliver an amazing experience!" [source]
9. Form-validation errors — inline, contextual, specific
References
Children
- The what / why / what-to-do-next triple (frontier)
- No-blame language (system owns the failure) (frontier)
- User terms vs internal terms (frontier)
- Error code conventions and status-code-vs-error-code distinction (frontier)
- Concrete next action or admit there is none (frontier)
- Conservative punctuation (exclamation marks, ALL CAPS, ellipses) (frontier)
- Internationalization (pluralization, register, length budget) (frontier)
- NN/g hostile patterns to avoid (frontier)
- Form-validation errors (inline, contextual, specific) (frontier)
- Separate user-facing string from log string with correlation IDs (frontier)
Frontier under this node: Concrete next action or admit there is none, Conservative punctuation (exclamation marks, ALL CAPS, ellipses), Error code conventions and status-code-vs-error-code distinction, Form-validation errors (inline, contextual, specific), Internationalization (pluralization, register, length budget), NN/g hostile patterns to avoid, No-blame language (system owns the failure), Separate user-facing string from log string with correlation IDs, The what / why / what-to-do-next triple, User terms vs internal terms