Skip to content

Sonnet rejects some /undo + /compact sessions that GPT still accepts #226

Description

@markthepixel

I think the Claude auth plugin may be part of the failure path here, but I can’t prove it’s the original cause.

What I’m seeing: after using /undo and then /compact in OpenCode, some sessions start failing on Sonnet with:

messages.2: tool_use ids were found without tool_result blocks immediately after ... Each tool_use block must have a corresponding tool_result block in the next message.

If I switch the same session from Sonnet to GPT, it works.

That makes me think one of two things is happening:

  • OpenCode is producing slightly malformed history after undo/compact
  • this plugin is not repairing / normalizing that history enough for Anthropic’s stricter validation

The reason I’m opening this here is that opencode-claude-auth does touch the message payload and already has repairToolPairs() in dist/transforms.js.

From what I can tell, that function checks whether matching tool_use / tool_result ids both exist somewhere in the message list, but it does not enforce the Anthropic rule that the matching tool_result has to be in the very next message.

So if undo/compact leaves history in a state where:

  • message N has a tool_use
  • the matching tool_result still exists, but not immediately after

then GPT may still tolerate it, but Sonnet rejects it, and the plugin lets it through because the pair technically still exists.

I inspected one broken session locally and found exactly that shape: the assistant message had the tool_use, and the next message was another assistant message, not the matching tool result wrapper.

So to be clear: I’m not saying this plugin necessarily creates the bad history. I suspect OpenCode core may be the original source, especially with /undo + /compact. But I do think this plugin may be related because it’s the Claude-specific path, and its repair logic seems too shallow for Anthropic’s adjacency requirement.

If helpful, I can put together a cleaner repro next time it happens. Right now the strongest evidence is:

  • broken session on Sonnet
  • same session works on GPT
  • happened after /undo + /compact
  • plugin has tool-pair repair logic, but it appears to check existence rather than adjacency

Thanks — posting here because this feels close enough to the Claude transform layer that it seemed worth flagging.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions