Programming · free software · the open webSubscribe via RSS

What Should a Machine-Readable Error Look Like?

From the earlier reference collection. Read the current software blog.

Return a predictable error shape with a stable code and helpful message, while keeping implementation details private.

Make failures recognizable

A client should be able to distinguish a failed request from a successful response without parsing a sentence. Use the appropriate HTTP status where relevant, then return a consistent body with fields such as code and message. The code is for program logic; the message helps a person understand what happened.

For example, a request with an invalid date might return {"code":"invalid_date","message":"Use a date in YYYY-MM-DD form."}. The same shape across endpoints lets client software handle errors in one place rather than special-case every route.

Keep codes stable and specific

Error codes should identify a category that clients can act on, such as not_found, invalid_parameter, or rate_limited. Avoid making clients branch on the exact wording of a message, since copy may need to change for clarity or localization.

Specificity helps when two errors require different user action. A missing required field and a malformed timestamp can both be invalid input, but separate codes or structured details can point the client to the right correction. Avoid exposing stack traces, file paths, database queries, or secrets in the response.

Add useful, safe context

A response can include a request identifier that support staff can use to locate a server-side log entry, provided it does not reveal sensitive information. For field validation, a list of safe parameter names and reasons can help a client show a precise correction. Keep internal exception text out of public responses.

Do not imply that a retry will help unless it might. A transient service failure may be retryable, while a bad parameter will remain bad until the request changes. If retry guidance is included, make it a documented field with clear meaning.

Test errors as part of the interface

Write examples for common failures and validate that each endpoint returns the same envelope. Check that successful responses do not accidentally reuse error fields in confusing ways, and that messages remain readable without leaking implementation details.

A consistent error contract turns failure into a usable part of an API. Clients can offer sensible next steps, operators can correlate reports, and users receive an explanation that helps them recover.

Suggest a correction · All posts