All guides
Claude

Troubleshooting tool use

Checked 09/15/2026View original
On this page

Symptom-to-fix tables for the most common tool-use errors. Each fix cross-references the page that owns the feature.

Claude calls the wrong tool

SymptomLikely causeFix
Claude calls tool A when you wanted tool BDescription ambiguitySharpen descriptions. Differentiate tools by WHEN to use them, not only WHAT they do. See Define tools.
Claude never calls your toolTool name collision or overly-generic schemaCheck for duplicate names across your tool list. Add input_examples to make the intended use concrete.
Claude calls with wrong parameter typesModel guessing at ambiguous schemaAdd strict: true (if your schema is in the supported subset) or add input_examples.

Claude invents tool parameters

SymptomLikely causeFix
Parameter that doesn't exist in your schemaModel over-generation without strict modeAdd strict: true if your schema is in the supported subset.
Parameter values outside your enumMissing strict mode or too-large enumShrink the enum or add input_examples showing valid choices.

Parallel tool calls don't work

SymptomLikely causeFix
Claude calls tools sequentially when parallel would be betterMessage history formattingSend multiple tool_result blocks in ONE user message, not one per turn. See Parallel tool use.
disable_parallel_tool_use seems ignoredSet too late in the conversationMust be set on the request that returns tool_use. Setting it on a later request has no effect on earlier tool calls.

Cache keeps invalidating

SymptomLikely causeFix
Every request is a cache misstool_choice, the thinking configuration, or output_config.effort varying between requestsKeep tool_choice stable or place the cache_control breakpoint before the variation point; hold the thinking configuration and effort level constant for the life of a cached conversation. See Tool use with prompt caching and Thinking and prompt caching.
Adding a tool mid-conversation breaks cacheTool prepended to the tools arrayUse defer_loading: true with tool search to append the tool inline instead of modifying the array head.

Errors at request time

ErrorCauseFix
tool_use ids were found without tool_result blocks immediately afterMissing tool_result for some tool_use ids, or tool_result is not the first content block in the user messageReturn one tool_result for every tool_use block in the assistant response. Put tool_result blocks before any text. See Handle tool calls and Parallel tool use.
was found without a corresponding <name>_tool_result blockThe previous assistant turn has a server_tool_use block with no result block (most often, Claude called it alongside a client tool), and either your next user message ended that turn (for example, with text after the tool_result blocks) or the resume request no longer defines that server tool (the message then ends with but no <name> tool was provided)Send a user message containing only the tool_result blocks for the client tool_use ids and keep the same tools array. See Stop reasons and fallback.
Unsupported regex feature in pattern field: ...A pattern in a strict tool's input_schema uses a regex feature that strict mode can't compile, such as a backreference, a lookaround, a word boundary, or a large {n,m} rangeSimplify the pattern. Anchored patterns with basic quantifiers, character classes, and groups are supported; see JSON Schema limitations.
All tools have defer_loading: trueNo tools visible to the modelAt least one tool must be immediately loaded. The tool search tool itself must never have defer_loading: true.

Error: thinking blocks cannot be modified

If a request fails with a 400 invalid_request_error whose message contains `thinking` or `redacted_thinking` blocks in the latest assistant message cannot be modified when continuing a conversation after a tool call, your application is altering the assistant's thinking blocks before sending them back. Send the entire assistant message back unchanged, then append your tool_result.

See Thinking blocks cannot be modified for the full error and fix steps.

Claude flags tool results as prompt injection

SymptomLikely causeFix
Claude refuses to act on a tool result, or asks the user to confirm instructions that came from itYour own instructions are being delivered inside the tool_result contentClaude is trained to treat instructions inside tool results as potentially untrusted third-party content. Move your instructions out of the tool result: send them in a user turn after the tool_result block, or, on supported models, in a mid-conversation system message. Keep the tool result to just the data. See Mitigate jailbreaks and prompt injections.

JSON escaping differences (Opus 4.6+)

SymptomCauseFix
String comparison on tool inputs fails with newer modelsUnicode and forward-slash escaping differs between model versionsParse with json.loads() or JSON.parse(). Never do raw string matching on serialized input.

Next steps