Skip to content

Phantom tool call in an extended-thinking turn permanently wedges the session #47274

Closed

Description

@lextiz

What happens

When a model calls a nonexistent tool during an extended-thinking turn, opencode stores it as an invalid tool part. On the next request that turn is the latest assistant message, and Anthropic rejects every continuation:

messages.N.content.M: `thinking` or `redacted_thinking` blocks in the latest assistant message cannot be modified. These blocks must remain as they were in the original response.

The session is stuck for good. Only editing storage or starting fresh recovers it.

Why

toModelMessagesEffect (packages/opencode/src/session/message-v2.ts) replays invalid tool parts as normal tool_use/tool_result blocks. They land interleaved between the signed thinking blocks, which breaks the byte-exact thinking replay Anthropic validates. The phantom call was never executed, so replaying it adds nothing but breakage (and re-injects the full tool list, see #41047).

Repro

  1. Anthropic/Bedrock model, extended thinking on.
  2. One turn calls a tool that does not exist (happens with some models / MCP setups).
  3. Continue the session -> permanent 400, "thinking blocks cannot be modified".

Fix

Drop invalid tool parts when building model messages; thinking blocks stay intact. PR incoming.

Related: #39291, #41738, #31188 (compaction variants of the same class), #41047, #33618 (phantom tool calls).

Activity

  1. russrapper15-png commented on Sep 4, 2026

    @russrapper15-png
  2. neriousy commented on Oct 19, 2026

    @neriousy
    Member

    In v2 a call to a tool that does not exist is kept exactly as the model sent it and answered with an error result saying the tool is not available; there is no longer a rewrite into an invalid tool part. History replay in packages/core/src/session/runner/to-llm-message.ts keeps the assistant's thinking blocks and tool calls in their original order, so the signed thinking is not modified on the next request. To get v2: npm i -g @opencode/cli@latest or curl -fsSL https://opencode.ai/v2/install | bash (desktop: update the app). If you still see this on v2, please open a new issue with the details.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions