DEV Community

Owen
Owen

Posted on Originally published at ofox.ai

Claude 400: Fix tool_use Without a Matching tool_result

A Claude error stating that tool_use has no matching tool_result typically indicates a structural conversation problem rather than a prompt issue. In the native Messages API, the assistant calls a client tool and the following user message should return the result with the matching ID. Verify this relationship before retrying.

This guide addresses this specific error category in custom integrations and clients such as OpenCode. Not every OpenCode HTTP 400 error stems from this cause. The guidelines follow Claude's tool-call handling documentation, verified September 14, 2026. Examples presented are synthetic message fragments, not traces from live API testing.

Find the unmatched ID first

Locate the referenced tool-use ID in the previous assistant message by reading the complete error message. Then inspect the following user message. Its tool_result.tool_use_id must reference that exact ID; the tool name cannot substitute for the identifier.

In the native Claude protocol, a tool result is a content block within a user message. There is no native role: "tool" in this message structure. If your adapter supports another provider's format, translate roles and fields rather than forwarding them unchanged.

Check Valid relationship Common failure
Identifier tool_use.id equals tool_result.tool_use_id New or truncated ID
Message order Assistant call followed by user results Another message inserted between them
Multiple calls Every client call gets its result Only the first result is retained
User content order Tool-result blocks before ordinary text A text block precedes the results

A minimal valid message fragment

This JSON shows only the relevant messages. A full request also requires the selected model, tool definition, token limit and remaining conversation. The demonstration result is invented for the example and must not replace executing a real tool.

[
  {
    "role": "assistant",
    "content": [
      {"type": "tool_use", "id": "toolu_demo", "name": "lookup", "input": {"key": "demo"}}
    ]
  },
  {
    "role": "user",
    "content": [
      {"type": "tool_result", "tool_use_id": "toolu_demo", "content": "demo result"}
    ]
  }
]
Enter fullscreen mode Exit fullscreen mode

Do not recreate the assistant message from text displayed in a chat window. Save the complete structured content returned by the API. Other blocks may need to remain in the conversation, including thinking data when the model and workflow require it. Signature validation is a separate issue covered in the Claude thinking-signature guide.

Parallel calls must return a complete set of results

When one assistant message requests two client tools, collect both results and include them in the immediately following user message. Do not send one result, insert another assistant turn, then attempt to return the second result to the original call. Place any permitted explanatory user text after the result blocks.

The official troubleshooting guide describes mixed server-tool workflows. If the same round has an unfinished server tool, the user message should contain only the client tool results, and the request should preserve the tools array. Do not generalize a minimal client-only example to every server-tool workflow.

Handle real tool failures without inventing success

A failed lookup or command can still have a correctly paired tool result. Return the same ID with is_error: true and an accurate error description when documented in the client-tool pattern. The protocol relationship and the underlying operation's success are separate checks.

If the client was interrupted, first determine whether the tool actually executed. A timeout in the interface does not prove that a file write, deployment or external request failed. Inspect the operation's state before repeating anything with side effects. Do not manufacture a successful result to satisfy validation, and do not automatically execute a consequential tool twice.

For development, reproduce the sequence with a harmless lookup in a disposable session. A read-only example reveals the pairing failure without risking another write or transaction. Capture the client version and the message immediately before and after the interruption.

Recover a damaged session carefully

Preserve a local copy of the relevant history before attempting repairs. If the original result is available, restore the correctly paired message using the client's supported recovery mechanism. If the history cannot be repaired safely, create a new session with a concise summary of verified work and pending actions, while retaining the old session for reference.

Deleting arbitrary tool blocks can change what the model believes happened. Deleting all conversation files is therefore not a default fix. When filing an issue, provide a small redacted sequence with roles, content types and matching IDs. Remove API keys, private tool arguments and sensitive results.

A client upgrade may be worth checking against its release notes, but this article does not identify one version that fixes every case. Historical issues establish that a failure occurred in a particular configuration; they do not prove the same bug remains in the latest release.

Why retrying alone does not solve it

The API validates the conversation structure before continuing the model turn. Sending the same unmatched sequence again leaves the structural problem unchanged. This conclusion follows from protocol rules, not a measured claim about every client's retry implementation.

An HTTP 429 or overloaded service calls for different investigation. Check the actual status and error body before applying this guide. For other access errors, use the model-not-found diagnostic; it addresses a different protocol and should not be confused with Claude tool-message pairing.

Frequently asked questions

Can a tool return an error and still satisfy the pairing requirement?

Yes. A truthful error result can match the original tool-use ID. Successful execution is not required to represent the failure correctly in the next message.

Should I use role tool with the native Claude API?

No. Native client tool results are user-message content blocks. An OpenAI-compatible adapter may expose another shape, so follow the protocol of the endpoint actually receiving the request.

Is starting a new session a complete fix?

It can isolate damaged history, but it does not repair an adapter that keeps dropping results. Check the serializer or client path that created the broken sequence before relying on the new session.

Why does retrying the same tool_result error fail?

The same unmatched message sequence remains invalid; repair the pairing and order first.

Where does a native Claude tool result go?

In a user content block with tool_use_id matching the preceding assistant tool_use ID.

Can I return a tool execution error?

Yes. Return a truthful error result for the original ID rather than inventing successful output.


Originally published on ofox.ai/blog.

Top comments (0)