An error message with a request id in it
A manager uploading a contract was shown a raw 400 from an API, JSON and all. It read as a broken product. It was a file that needed swapping — and the difference is entirely in who the message was written for.
Here is what somebody saw on screen when they uploaded a contract:
400 {"type":"error","error":{"type":"invalid_request_error",
"message":"messages.0.content.0.image.source.base64: The image was
specified using the image/png media type, but the image appears to be
a image/jpeg image"},"request_id":"req_011Cepf1uKyNSKvTJxubJAT6"}
Every word of that is true. None of it is for them.
Where these come from
Any system that talks to another company's service — a payment provider, a delivery platform, a document reader, an email service — will sometimes get an error back. Those errors are written for the developer integrating the service. They are precise, they carry identifiers for support tickets, and they assume the reader can act on a field path.
The lazy thing to do with such an error is show it. It is right there, it is
descriptive, and passing it through is one line of code. The result is that a
person on a counter is handed a sentence about content.0.image.source
and reasonably concludes the software is broken.
It was not broken. Their file needed swapping. Those are wildly different conclusions and the message chose the wrong one for them.
What the person needed instead
Three things, in order: what happened, whether it is their fault, and what to do next. The version they get now says the file could not be read as a contract, suggests a clearer photo or a PDF, and reminds them the form can be filled in by hand — which is the actual fallback and was true the whole time.
The other errors from the same service get the same treatment. A key that has stopped working says so, and says where to change it. Too many requests at once says wait a moment. A service having a bad day says try again in a minute. Each one names an action.
The rule underneath
An error message is a piece of the product. It gets written, not forwarded. If a message contains a field path, a stack frame, a request id or a status code, it was written for somebody else and needs translating before it reaches a person doing their job.
There is a practical version of this you can check on any system you are buying: make it fail. Upload the wrong thing. Unplug the network mid-save. If what comes back has punctuation in it that belongs in a config file, you now know what your staff will see at half past seven on a Friday.