Error Messages Are the Most Neglected Copy in Your Product

Every product has a page that has been rewritten twenty times. It is the landing page. Three people argued over the headline, someone ran a test, the word "simple" got removed and put back twice.

The same product has forty error messages that were written by a developer at eleven at night, in a hurry, with no intention of anyone ever reading them.

Those forty strings are read by your users at the worst moment they will ever have with your product. That is a strange allocation of care.

Errors are the only copy people read closely

Nobody reads your feature descriptions. Everybody reads the red text, because the red text is standing between them and the thing they were trying to do.

It is the highest attention moment in the entire experience and it usually says Something went wrong. Which is true, useless, and slightly insulting, because the user knows something went wrong. That is why they are reading.

What a good error message does

Three jobs, in this order.

Say what happened, in the user's terms. Not the system's terms. "We could not reach the server" describes your architecture. "Your changes are not saved yet" describes their life. The user does not have a server. They have a document.

Say whether their work is safe. This is the one everyone forgets and the one people actually care about. The fear behind almost every error is did I just lose it. Answer that first if you answer nothing else.

Say what to do next. One action, ideally a button rather than an instruction. "Try again" as a button beats "please try again later" as a sentence, because one of them is a way out and the other is a shrug.

The tone problem

There is a period in every product's life where somebody decides errors should be funny. Please do not.

Humour works when the stakes are low. A cute 404 on a marketing site is fine. A cute message when someone's payment failed or their upload of an hour of work vanished reads as a company that does not understand what it just did to your afternoon.

Match the tone to the cost. Small problem, light touch. Real problem, plain and direct and slightly apologetic. And never blame the user. "Invalid input" tells someone they are wrong. "That date is in the past" tells them what to fix.

The messages nobody audits

Pull every error string in your product into one document and read them together. I have done this on several products and it is always revealing. You will find:

  • The same problem described three different ways in three parts of the app
  • Errors that mention internal service names no user has heard of
  • Errors with no way forward at all, just a statement and a wall
  • Errors that fire for two completely unrelated causes because one catch block covers both
  • At least one message that was clearly a placeholder and shipped anyway

That last one is not rare. I have found actual test strings in production in companies with thousands of employees.

Design the failures on purpose

When I design a flow now, I write the failure states at the same time as the happy path, in the same file, before anything is built. Not afterwards, because afterwards means never, and it means the strings get invented by whoever hits the branch first.

The happy path is what you demo. The failure path is what people remember. Someone whose payment failed and who was told clearly what happened and what to do next will forgive you. Someone who got a red box with a code in it will tell a friend.

Forty strings. A day of work. Almost nobody does it.

← All posts