How Should Tools Report Errors to Claude?
Return the failure as a tool_result with is_error: true, and say what went wrong and what Claude should try next. Don't throw an exception that ends the loop, and don't send an empty success. A message like "Rate limit exceeded. Retry after 60 seconds." gives Claude something to act on.
Review the error handling in these tool functions: [paste code] For each way a tool can fail, make sure it returns a tool_result with is_error: true and a message that says: 1. what went wrong, in plain words 2. whether retrying could help, and when 3. what to do instead, naming the parameter or tool Remove stack traces and internal details from messages. Don't return an empty result when something failed. For tools with side effects, say whether the action may have partly happened. Add a retry cap for me to enforce in code, and list the failures that should stop the run.
- Set is_error: true
- Say what went wrong
- Say what to try next
- Return only "failed"
- Send a raw stack trace
- Send an empty success
Try it now
- 1Find a tool that can fail, and force the failure with a bad ID or an expired key.
- 2Log the exact
tool_resultClaude receives. If it's just "failed", rewrite it using the format above. - 3Run the same request again and watch what Claude does on its next turn.
- 4You'll know it worked if Claude corrects the input or tells the user something accurate. If you get a 400 about
tool_useids, check that every call has a result immediately after it.
Use it when
Use it for any client tool that can fail: network calls, permissions, not-found lookups, rate limits, validation and timeouts. It matters most in unattended agents, where nobody is watching to rescue a run that's gone wrong.
Skip it when
Anthropic's docs say you don't need to handle is_error for server tools such as web search, since Claude handles those errors itself. And don't let an agent retry forever. Some failures need to stop the run and alert a person, such as a payment that may have gone through.
Why it works
Anthropic's docs say that when you return an error result, Claude incorporates it into its response, and that if a request is invalid or missing parameters, Claude will retry 2 to 3 times with corrections before apologizing to the user. They advise instructive error messages rather than generic ones like "failed", so Claude can recover without guessing. The tool-writing guide says the same about opaque codes and tracebacks. Claude can only reason about what's in the result, so whatever you put there becomes its understanding of what happened.
Example
Your orders_get tool gets an unknown ID. Instead of "404", it returns is_error: true with: "No order found with ID 8841. IDs have the form ORD-12345. If you only have a customer email, call orders_search with the email." Claude can now reformat the ID, or switch tools, without asking the user what a 404 means.
Going further
To eliminate invalid calls, set strict: true on the tool, which Anthropic says guarantees inputs match your schema. That handles shape, not meaning, so keep clear errors for a well-formed ID that doesn't exist. Formatting is strict too: results must come right after the matching tool use, and tool_result blocks must come first in the user message, or you get a 400. Also treat results as untrusted. Anthropic warns that tool results from web pages, email or uploads can carry prompt injection, so keep that content in tool_result blocks, not in system or plain text blocks.
Common mistakes
- Returning
is_error: truewith "failed", which tells Claude a problem exists but nothing else. - Returning an empty success on failure, so Claude confidently reports that there were no results.
- Putting text before the
tool_resultblocks in the user message, which causes a 400 error. - Saying a write failed when it may have partly happened, so Claude retries and duplicates the action.
Sources
- Handle tool calls, Claude Platform Docs
- Writing tools for agents, Anthropic Engineering
- Structured outputs, Claude Platform Docs
Checked 6 November 2026. Products change often, so confirm details with the vendor.