DEV Community

Manuel Garcia
Manuel Garcia

Posted on

Error Messages Are Writing, Too

Error messages are some of the most carefully read sentences in any piece of software. They appear at the exact moment the reader is stuck, often a little frustrated, and looking for help. Yet they are frequently written last, in a hurry, by someone thinking about the code rather than the person on the other side of it.

The good news is that a useful error message follows a simple pattern, and it can be learned like any other kind of editing.

The three parts of a useful message

A clear error message answers three questions:

  1. What happened?
  2. Why did it happen, if that is known?
  3. What can the reader do now?

Most weak messages answer only the first question, and sometimes not even that.

Before:

Error: invalid input.

After:

The date "31.02.2026" could not be read. February has no 31st day. Please enter a date in the format DD.MM.YYYY.

The second version is longer, but every word earns its place. The reader knows which value was wrong, why it was rejected and what a correct value looks like.

Name the thing, not the category

"Invalid input", "operation failed" and "something went wrong" describe a category of problem. The reader needs the specific case.

Whenever the program knows which file, field, value or setting caused the problem, include it in the message. "Could not open config.yaml" is immediately useful. "Could not open file" sends the reader searching.

This also helps when people copy the message into a search engine or a support request. A specific message leads to specific answers.

Speak to the reader, not about the code

Internal terms leak easily into error text: exception names, function names, abbreviations that only the team uses. They make sense to the author and to nobody else.

Before:

NullReferenceException in UserProfileLoader.

After:

Your profile could not be loaded because no account is linked to this email address.

Technical details still have a place. Developers debugging the problem may need the exception and the stack trace. Put those in logs, or below the human-readable message, clearly separated. The first line should be readable by the person who actually sees it.

Do not blame, do not joke

Tone matters more than usual here, because the reader is already having a bad moment.

  • Avoid blame. "You entered an invalid password" sounds like an accusation. "The password does not match this account" states the same fact neutrally.
  • Avoid jokes. A playful "Oops!" can feel friendly the first time and irritating the tenth time, especially when work has been lost.
  • Avoid false certainty. If the cause is only a guess, say "This may be caused by..." rather than presenting it as fact.

Calm, plain language works best. The aim is to sound like a helpful colleague, not a machine and not a comedian.

Offer a way forward

The most important part of an error message is the last one: what the reader can do next. Even when the program cannot fix the problem, it can usually point somewhere.

  • Retry later, if the problem is temporary.
  • Correct a specific value, and show the expected format.
  • Check a specific setting, and name where it is.
  • Contact support, and say what information to include.

A message without a next step leaves the reader at a dead end. A message with one turns a failure into a short detour.

Review your errors like any other text

Collect the error messages in your project in one list and read them in a row. This simple exercise reveals a lot: inconsistent wording, messages that say the same thing in five different ways, and messages that say nothing at all.

Edit them as you would edit any other text. Check that each one names the problem, explains it where possible and offers a next step. They are short, but for the reader in that moment, they may be the most important words in the whole product.

Top comments (1)

Collapse
 
lilnickyai profile image
Lil Nicky AI •

The three-question pattern is the part I would pin: most errors I see answer only 'what happened' and stop there. One practice that makes this pattern stick in a codebase: during code review, treat a missing 'what to do now' as a review comment on its own, the same way you would flag a missing null check. It turns error messages from an afterthought into something the whole team maintains.