---
title: "Your Error Messages Are Your AI Agent's Only Lifeline"
description: "When an LLM agent hits an error, the message is all it has. Machine-parseable codes, recovery suggestions, and deterministic structure turn errors into agent guidance."
canonical: https://nowah.xyz/blog/error-messages-ai-agent-lifeline
lastModified: "2026-08-07T08:11:28.545Z"
---

# Your Error Messages Are Your AI Agent's Only Lifeline

When an LLM agent hits an error, the message is all it has. Machine-parseable codes, recovery suggestions, and deterministic structure turn errors into agent guidance.

An agent hit an error and retried the same invalid request 47 times. Each retry produced the same error. Each error said "Bad Request." Nothing in the response told the agent what was wrong with the request, whether retrying would help, or what it should do instead.

After 47 attempts, the agent hit its retry limit and gave up. The user saw: "I was unable to complete your request. Please try again." The user tried again. The agent retried 47 more times. Same result.

This is [what happens](/blog/what-happens-after-you-book) when error messages are designed for humans glancing at a log and not for AI agents making autonomous decisions. A human developer would read "Bad Request," check the request body, realize the airport code is invalid, and fix it. An agent does not have that debugging instinct. It has the error response and nothing else.

## Machine-parseable codes versus human-readable messages

![Illustration for this section](https://pics.nowah.xyz/website-media/developer-experience-027-img-1-error-fields.webp)

The distinction between these two is the foundation of agent-friendly error design.

A human-readable message: "The selected flight offer has expired. Please search again."

A machine\-parseable code: \`OFFER\_EXPIRED\`

Humans read the message. Agents parse the code. Both need to be present in every error response, and they serve fundamentally different purposes.

The code is a stable identifier that the agent can use in a decision tree\. \`OFFER\_EXPIRED\` always means the same thing\. The agent can have a hardcoded response: when I see \`OFFER\_EXPIRED\`, I should perform a new search\. This mapping is deterministic\. It does not depend on natural language understanding or interpretation\.

The message is for the human reviewing the agent's logs or for display to the end user. It explains the situation in natural language. The agent might pass it along to the user, or it might use it as context for generating a more helpful response.

If you only provide the message without a code, the agent has to interpret natural language to decide what to do. "The offer has expired" and "This offer is no longer available" mean the same thing, but an agent parsing text might treat them differently. Codes eliminate this ambiguity.

## Recovery suggestions

The most impactful addition to agent-friendly errors is a recovery suggestion. This is a structured field that tells the agent exactly what to do next.

```
{
 "success": false,
 "error": {
 "code": "OFFER_EXPIRED",
 "message": "The selected flight offer has expired.",
 "details": "Offer flt_abc123 expired at 2026-03-15T14:00:00Z.",
 "recovery": {
 "action": "search_again",
 "description": "Search for fresh offers on the same route.",
 "retryable": false
 },
 "docs": "https://docs.nowah.com/errors/OFFER_EXPIRED",
 "requestId": "req_xyz789"
 }
}
```

The \`recovery\` object contains:

- \`action\`: a machine\-readable recovery action the agent can match on\.
- \`description\`: a human\-readable explanation of the recovery\.
- \`retryable\`: whether retrying the exact same request might succeed\.

The \`retryable\` field is critical\. An agent that receives \`retryable: false\` knows immediately that retrying is pointless\. It should try the recovery action instead\. An agent that receives \`retryable: true\` knows that a retry \(possibly after a delay\) is appropriate\.

Without this field, agents default to retrying everything. That produces the 47-retry scenario from the opening. With it, agents make informed decisions about whether to retry or take alternative action.

## Error code to behavior mapping

![Supporting diagram](https://pics.nowah.xyz/website-media/developer-experience-027-img-2-decision-tree.webp)

Our six error categories map to specific agent behaviors:

**VALIDATION\_**\* errors are never retryable\. The request is wrong and needs to be changed\. The details field specifies which parameters are invalid and what values are expected\. The agent should fix the parameters and resubmit\.

**AUTH\_**\* errors are sometimes retryable\. An expired token can be refreshed and the request retried\. Invalid credentials require user intervention\. The recovery field distinguishes between these cases\.

**RATE\_LIMIT\_**\* errors are always retryable after a delay\. The \`Retry\-After\` header specifies exactly how long to wait\. The agent should wait that duration and retry unchanged\.

**PROVIDER\_**\* errors are sometimes retryable\. An upstream timeout might resolve on retry\. A provider outage might not\. The recovery field indicates whether retry is likely to help and suggests alternatives \(try a different provider, broaden the search parameters\)\.

**BOOKING\_**\* errors depend on the specific code\. \`OFFER\_EXPIRED\` is not retryable — search again\. \`SEAT\_UNAVAILABLE\` is not retryable for that specific seat — try a different seat or flight\. \`PAYMENT\_DECLINED\` requires user intervention to update payment details\.

**INTERNAL\_**\* errors are our fault and usually retryable\. The agent should wait briefly and retry\. If the error persists, it should inform the user that the service is experiencing issues\.

This mapping covers every error our API can produce. An agent that implements this decision tree handles failures gracefully without human intervention for most cases.

## Testing error handling

We maintain evaluation datasets specifically for error-path behavior. These datasets send requests designed to trigger every error category and verify that agents respond correctly.

The test cases include:

- Booking with an expired offer (should search again, not retry)
- Searching with an invalid airport code (should fix the code, not retry)
- Hitting a rate limit (should wait and retry)
- Encountering a provider timeout (should retry once, then search alternate providers)
- Submitting a booking with insufficient payment (should inform the user)

Each test case specifies the expected agent behavior. The evaluation framework compares the agent's actual response against the expected behavior and scores the interaction.

We run these evaluations on every change to our error responses. If we rephrase an [error message](/blog/anatomy-of-perfect-error-message), the evaluation verifies that agent behavior does not degrade. If we add a new error code, we add corresponding test cases. The evaluation suite is the safety net that ensures our errors continue to guide agents correctly.

The bottom line: error messages are not just failure reports. For AI agents, they are instructions. Every error you send is a decision the agent has to make. The clearer and more structured those instructions are, the better the agent performs. Invest in your error design with the same rigor you invest in your success responses. The agents consuming your API will be grateful — or at least, they will stop retrying 47 times.

---

Nowah is an AI travel agent that searches and books real flights and hotels through conversation — no filters, no thirty open tabs. [Plan your next trip](https://app.nowah.xyz).
