Slash command during in-flight server-tool call orphans tool_result, wedges session (400)

Open 💬 0 comments Opened Jun 10, 2026 by elspethsoup

Summary

Running a local slash command while a server-side tool call is in flight permanently wedges the session with a recurring 400 from the Anthropic API.

What happens

Server-side tools (e.g. the advisor tool) emit a server_tool_use block, and the API requires the matching *_tool_result block to follow it within the same assistant message (use-then-result, contiguous).

If the user runs a local slash command (e.g. /color) after server_tool_use is written but before the result returns, Claude Code writes the command's system transcript entries (the <command-name> line and the <local-command-stdout> line) between the server_tool_use block and its *_tool_result block — even though all blocks share the same assistant message.id.

On reassembly, those interleaved system entries split the single assistant message into two API messages: the server_tool_use ends up in message N, and the orphaned *_tool_result becomes content[0] of message N+1.

Result

Every subsequent turn replays the broken history, so the API rejects each request:

API Error: 400 messages.<N>.content.0: unexpected `tool_use_id` found in
`advisor_tool_result` blocks: srvtoolu_XXXX. Each `advisor_tool_result` block
must have a corresponding `server_tool_use` block before it.

The session is permanently wedged — it cannot recover on its own because the same malformed history is re-sent on every turn. The only recoveries are rewinding to before the tool call (loses all subsequent work) or hand-editing the session .jsonl to remove the interleaved system entries.

Repro

  1. Trigger a server-side tool call (e.g. advisor).
  2. While it's in flight, run any local slash command (/color, etc.).
  3. Observe the recurring 400 on the next and every following turn.

Suggested fix

When persisting transcript entries, do not interleave local-command system entries inside an assistant message that has an open (un-resulted) server_tool_use block. Either defer the slash-command entries until after the *_tool_result is written, or ensure reassembly keeps server_tool_use + its *_tool_result contiguous in the same API message regardless of interleaved local system entries.

Environment

  • Claude Code, model claude-opus-4-8
  • macOS (Darwin 25.x)

View original on GitHub ↗