tool_result

Tools

Definition

A content block type in the user message that returns the output of a tool execution back to Claude. Must include the 'tool_use_id' matching the original tool_use block. Can be text, images, or error messages. Claude processes the result and continues reasoning.

Example Usage

After executing a tool, append a user message with role='user' containing a tool_result block with the execution output.

In Depth

A tool_result content block is how your code hands execution output back to Claude. It lives inside a user role message and acts as the answer to one specific tool_use request. The contract is straightforward but strict:

  • type: must be "tool_result".
  • tool_use_id: must exactly match the id from the original tool_use block.
  • content: the payload — a string, an array of content blocks (text or image), or omitted for empty results.
  • is_error: optional boolean. Set to true when the tool call failed. This is preferable to raising an exception or returning an empty result, because Claude can read the error detail and adjust its approach.

The single-message rule is the most commonly misunderstood constraint: all tool_result blocks for a given assistant turn must arrive in one user message. If Claude requested three tools in parallel, your user message must have three tool_result content blocks. Sending them in separate messages causes an API error.

Returning rich content is supported. For screenshot tools or chart generators, you can return an image block inside content. For structured data tools, returning valid JSON as a string is conventional and allows Claude to parse and reason over it.

When is_error: true, pair it with a descriptive content string explaining what went wrong and, when possible, what Claude should try instead. This feeds directly into error-response-design patterns — a well-formed error result often prevents redundant retry loops.

Claude does not modify or validate the content you provide; it reasons over whatever you return. This means that if your tool silently returns stale or truncated data, Claude has no way to detect the problem. Accuracy of tool results is entirely the developer's responsibility.

See Structured Error Response Design for patterns on making errors actionable.

How It Compares

ScenarioCorrect approachWrong approach
Tool raised an exceptionSet is_error: true, include error message in contentReturn empty string or throw silently
Tool returned no dataReturn content: "No results found" with is_error: falseOmit content entirely or set is_error: true
Two tool_use blocks in one responseOne user message with two tool_result blocksTwo separate user messages each with one block
Tool returned an imagecontent: [{type: "image", source: {...}}]Encode binary in a text string
ID from tool_use was toolu_01tool_use_id: "toolu_01"tool_use_id: "tool_1" or any other value

How It's Tested & Common Confusions

Exam questions on tool_result tend to focus on:

  • ID matching: given a tool_use block with a specific id, which tool_result is valid? (Only the one whose tool_use_id equals that id.)
  • Single-message rule: if Claude returned two tool_use blocks, how many user messages are required to return results? (One — with two tool_result content blocks.)
  • is_error usage: when should you set is_error: true vs. returning a success result with error text in the content? (is_error signals to Claude that the call itself failed, not that the operation returned an empty set.)
  • Content types: can tool_result carry an image? (Yes — use an image content block inside the content array.)

Frequently Asked Questions

Is it safe to return raw JSON objects in the `content` field?

`content` accepts strings or arrays of content blocks, not raw JSON objects. To return structured data, serialize your object to a JSON string and pass that string as the content value. Claude will parse and reason over the stringified JSON correctly.

What does Claude do differently when `is_error` is true?

Claude reads the error description and typically revises its approach — for example, choosing different parameters, trying a fallback tool, or surfacing the problem to the user rather than silently retrying. Without `is_error: true`, Claude may interpret a failure message as legitimate output and continue on an incorrect path.