Repository Public
1---2title: Handle tool calls3url: https://platform.claude.com/docs/en/agents-and-tools/tool-use/handle-tool-calls4description: Parse tool_use blocks, format tool_result responses, and handle errors with is_error.5---67This page covers the tool-call lifecycle: reading `tool_use` blocks from Claude's response, formatting `tool_result` blocks in your reply, and signaling errors. For the SDK abstraction that handles this automatically, see [Tool Runner](https://platform.claude.com/docs/en/agents-and-tools/tool-use/tool-runner).89<Note>10 **Simpler with Tool Runner:** The manual tool handling described on this page is automatically managed by [Tool Runner](https://platform.claude.com/docs/en/agents-and-tools/tool-use/tool-runner). Use this page when you need custom control over tool execution.11</Note>1213Claude's response differs based on whether it uses a [client or server tool](https://platform.claude.com/docs/en/agents-and-tools/tool-use/overview#how-tool-use-works).1415## Handling results from client tools1617The response will have a `stop_reason` of `tool_use` and one or more `tool_use` content blocks that include:1819* `id`: A unique identifier for this particular tool use block. This will be used to match up the tool results later.20* `name`: The name of the tool being used.21* `input`: An object containing the input being passed to the tool, conforming to the tool's `input_schema`.2223A `tool_use` block for a member of the [computer use](https://platform.claude.com/docs/en/agents-and-tools/tool-use/computer-use-tool) or [browser use](https://platform.claude.com/docs/en/agents-and-tools/tool-use/browser-use-tool) toolset also carries a `toolset_name` field (`"computer"` or `"browser"`). Its `name` is the member tool Claude is calling, such as `screenshot` or `navigate`, so dispatch those blocks on both fields.2425<Accordion title="Example API response with a `tool_use` content block">26 ```json JSON27 {28 "id": "msg_01Aq9w938a90dw8q",29 "model": "claude-opus-5",30 "stop_reason": "tool_use",31 "role": "assistant",32 "content": [33 {34 "type": "text",35 "text": "I'll check the current weather in San Francisco for you."36 },37 {38 "type": "tool_use",39 "id": "toolu_01A09q90qw90lq917835lq9",40 "name": "get_weather",41 "input": { "location": "San Francisco, CA", "unit": "celsius" }42 }43 ]44 }45 ```46</Accordion>4748When you receive a tool use response for a client tool, you should:49501. Extract the `name`, `id`, and `input` from the `tool_use` block.51522. Run the actual tool in your codebase corresponding to that tool name, passing in the tool `input`.53543. Continue the conversation by sending a new message with the `role` of `user`, and a `content` block containing the `tool_result` type and the following information:5556 * `tool_use_id`: The `id` of the tool use request this is a result for.57 * `content` (optional): The result of the tool, as a string (for example, `"content": "15 degrees"`), a list of nested content blocks (for example, `"content": [{"type": "text", "text": "15 degrees"}]`), or a list of document blocks (for example, `"content": [{"type": "document", "source": {"type": "text", "media_type": "text/plain", "data": "15 degrees"}}]`). These content blocks can use the `text`, `image`, `document`, or [`search_result`](https://platform.claude.com/docs/en/build-with-claude/search-results) types.58 * `is_error` (optional): Set to `true` if the tool execution resulted in an error.5960A `tool_result` that answers a computer use or browser use member block must also echo the same `toolset_name` value as the `tool_use` block; a member result that omits it is rejected. Its `content` is also narrower: a member result may contain only `text` and `image` blocks, and a browser use result may add one [`browser_state`](https://platform.claude.com/docs/en/agents-and-tools/tool-use/browser-use-tool#track-tabs-and-page-state) block (the [tab-management members](https://platform.claude.com/docs/en/agents-and-tools/tool-use/browser-use-tool#tab-management-results) return only that block).6162<Note>63 **Important formatting requirements:**6465 * Tool result blocks must immediately follow their corresponding tool use blocks in the message history. You cannot include any messages between the assistant's tool use message and the user's tool result message.66 * In the user message containing tool results, the tool\_result blocks must come FIRST in the content array. Any text must come AFTER all tool results.67 * If the assistant turn also called a [server tool](https://platform.claude.com/docs/en/agents-and-tools/tool-use/server-tools) that has no result block yet, the user message must contain only `tool_result` blocks. Text after the results ends the turn early; for a server tool Claude called directly, the request then fails with a 400 error that names the unresolved server tool. See [Stop reasons and fallback](https://platform.claude.com/docs/en/build-with-claude/handling-stop-reasons#tool-use).6869 For example, this will cause a 400 error:7071 ```json72 {73 "role": "user",74 "content": [75 { "type": "text", "text": "Here are the results:" }, // ❌ Text before tool_result76 { "type": "tool_result", "tool_use_id": "toolu_01" /* ... */ }77 ]78 }79 ```8081 This is correct when the assistant turn calls only client tools:8283 ```json84 {85 "role": "user",86 "content": [87 { "type": "tool_result", "tool_use_id": "toolu_01" /* ... */ },88 { "type": "text", "text": "What should I do next?" } // ✅ Text after tool_result89 ]90 }91 ```9293 If you receive an error like "tool\_use ids were found without tool\_result blocks immediately after", check that your tool results are formatted correctly.94</Note>9596<Warning>97 Tool results often carry content from sources outside your control: web pages, inbound email, user uploads, third-party APIs. Treat that content as untrusted: an attacker who can influence it may embed instructions that try to redirect Claude (indirect prompt injection). Keep untrusted content inside `tool_result` blocks rather than `system` prompts or plain user `text` blocks, and see [Mitigate jailbreaks and prompt injections](https://platform.claude.com/docs/en/test-and-evaluate/strengthen-guardrails/mitigate-jailbreaks#indirect-prompt-injection) for further hardening.98</Warning>99100<AccordionGroup>101 <Accordion title="Example of successful tool result">102 ```json JSON103 {104 "role": "user",105 "content": [106 {107 "type": "tool_result",108 "tool_use_id": "toolu_01A09q90qw90lq917835lq9",109 "content": "15 degrees"110 }111 ]112 }113 ```114 </Accordion>115116 <Accordion title="Example of tool result with images">117 ```json JSON118 {119 "role": "user",120 "content": [121 {122 "type": "tool_result",123 "tool_use_id": "toolu_01A09q90qw90lq917835lq9",124 "content": [125 { "type": "text", "text": "15 degrees" },126 {127 "type": "image",128 "source": {129 "type": "base64",130 "media_type": "image/jpeg",131 "data": "/9j/4AAQSkZJRg..."132 }133 }134 ]135 }136 ]137 }138 ```139 </Accordion>140141 <Accordion title="Example of empty tool result">142 ```json JSON143 {144 "role": "user",145 "content": [146 {147 "type": "tool_result",148 "tool_use_id": "toolu_01A09q90qw90lq917835lq9"149 }150 ]151 }152 ```153 </Accordion>154155 <Accordion title="Example of tool result with documents">156 ```json JSON157 {158 "role": "user",159 "content": [160 {161 "type": "tool_result",162 "tool_use_id": "toolu_01A09q90qw90lq917835lq9",163 "content": [164 { "type": "text", "text": "The weather is" },165 {166 "type": "document",167 "source": {168 "type": "text",169 "media_type": "text/plain",170 "data": "15 degrees"171 }172 }173 ]174 }175 ]176 }177 ```178 </Accordion>179</AccordionGroup>180181After receiving the tool result, Claude will use that information to continue generating a response to the original user prompt.182183## Handling results from server tools184185Claude executes the tool internally and incorporates the results directly into its response without requiring additional user interaction.186187<Note>188 A response can contain both a client `tool_use` block and a `server_tool_use` block that has no result block. That server tool call is not finished yet, and its result block arrives in a later response. Reply with a user message that contains only the `tool_result` blocks for the client tools and keep the same `tools` array; for a server tool Claude called directly, the API runs it on that request and the next response starts with its result block. See [Stop reasons and fallback](https://platform.claude.com/docs/en/build-with-claude/handling-stop-reasons#tool-use).189</Note>190191<Tip>192 **Differences from other APIs**193194 Unlike APIs that separate tool use or use special roles like `tool` or `function`, the Claude API integrates tools directly into the `user` and `assistant` message structure.195196 Messages contain arrays of `text`, `image`, `tool_use`, and `tool_result` blocks. `user` messages include client content and `tool_result`, while `assistant` messages contain AI-generated content and `tool_use`.197</Tip>198199## Handling errors with is\_error200201There are a few different types of errors that can occur when using tools with Claude:202203<AccordionGroup>204 <Accordion title="Tool execution error">205 If the tool itself throws an error during execution (for example, a network error when fetching weather data), you can return the error message in the `content` along with `"is_error": true`:206207 ```json JSON208 {209 "role": "user",210 "content": [211 {212 "type": "tool_result",213 "tool_use_id": "toolu_01A09q90qw90lq917835lq9",214 "content": "ConnectionError: the weather service API is not available (HTTP 500)",215 "is_error": true216 }217 ]218 }219 ```220221 Claude will then incorporate this error into its response to the user. For example: "I'm sorry, I was unable to retrieve the current weather because the weather service API is not available. Please try again later."222223 <Tip>224 Write instructive error messages. Instead of generic errors like `"failed"`, include what went wrong and what Claude should try next (for example, `"Rate limit exceeded. Retry after 60 seconds."`). This gives Claude the context it needs to recover or adapt without guessing.225 </Tip>226 </Accordion>227228 <Accordion title="Invalid tool name">229 If Claude's attempted use of a tool is invalid (for example, missing required parameters), it usually means that there wasn't enough information for Claude to use the tool correctly. Your best bet during development is to try the request again with more-detailed `description` values in your tool definitions.230231 However, you can also continue the conversation forward with a `tool_result` that indicates the error, and Claude will try to use the tool again with the missing information filled in:232233 ```json JSON234 {235 "role": "user",236 "content": [237 {238 "type": "tool_result",239 "tool_use_id": "toolu_01A09q90qw90lq917835lq9",240 "content": "Error: Missing required 'location' parameter",241 "is_error": true242 }243 ]244 }245 ```246247 If a tool request is invalid or missing parameters, Claude will retry 2-3 times with corrections before apologizing to the user.248249 <Tip>250 To eliminate invalid tool calls entirely, use [strict tool use](https://platform.claude.com/docs/en/agents-and-tools/tool-use/strict-tool-use) with `strict: true` on your tool definitions. This guarantees that tool inputs will always match your schema exactly, preventing missing parameters and type mismatches.251 </Tip>252 </Accordion>253254 <Accordion title="Server tool errors">255 When server tools encounter errors (for example, network issues with Web Search), Claude will transparently handle these errors and attempt to provide an alternative response or explanation to the user. Unlike client tools, you do not need to handle `is_error` results for server tools.256257 For web search specifically, possible error codes include:258259 * `too_many_requests`: Rate limit exceeded260 * `invalid_input`: Invalid search query parameter261 * `max_uses_exceeded`: Maximum web search tool uses exceeded262 * `query_too_long`: Query exceeds maximum length263 * `unavailable`: An internal error occurred264 </Accordion>265</AccordionGroup>266267## Next steps268269<CardGroup cols={3}>270 <Card title="Parallel tool use" icon="grid" href="https://platform.claude.com/docs/en/agents-and-tools/tool-use/parallel-tool-use">271 Handle responses where Claude calls several tools in a single turn.272 </Card>273274 <Card title="Tool Runner (SDK)" icon="wrench" href="https://platform.claude.com/docs/en/agents-and-tools/tool-use/tool-runner">275 Let the SDK manage the `tool_use` loop, result formatting, and retries for you.276 </Card>277278 <Card title="Define tools" icon="hammer" href="https://platform.claude.com/docs/en/agents-and-tools/tool-use/define-tools">279 Write schemas and descriptions that steer Claude toward the right tool.280 </Card>281</CardGroup>282