Skip to content

Bug: Session corrupted when tool execution is aborted - missing tool_result causes API rejection #8312

Description

@popododo0720

Summary

When a tool execution is aborted (e.g., user cancels during tool run), the session becomes permanently corrupted. Subsequent messages fail with Anthropic API error: tool_use ids were found without tool_result blocks.

Environment

  • OS: Linux
  • Provider: Anthropic (Claude)

Steps to Reproduce

  1. Start a conversation that triggers tool calls
  2. Abort/cancel during tool execution (e.g., press Ctrl+C or cancel button)
  3. Try to continue the conversation in the same session
  4. API returns error: messages.N: tool_use ids were found without tool_result blocks immediately after: toolu_XXXXX

Root Cause Analysis

When a tool is aborted, the tool call part is saved with status: "error" and error: "Tool execution aborted":

{
  "type": "tool",
  "callID": "toolu_019ArjTH5XqPy66uTLZ8KHpM",
  "tool": "edit",
  "state": {
    "status": "error",
    "input": {},
    "error": "Tool execution aborted",
    "time": { "start": 1768350546106, "end": 1768350546106 }
  }
}

However, no corresponding tool_result message is created. When the conversation is reconstructed for the next API call, it sends the tool_use block but not a matching tool_result, violating Anthropic's API contract.

Current Behavior in agent.go

In streamAndHandleEvents() (line 350-420), tool results are properly generated for:

  • ✅ Context cancellation (ctx.Done()) - lines 353-364
  • ✅ Permission denied - lines 396-410

But not for:

  • ❌ Tool execution errors/aborts that occur through other paths

Suggested Fix

In internal/llm/agent/agent.go, ensure ALL tool calls get a tool_result, even on error:

// After tool.Run() fails with any error (not just permission denied)
if toolErr != nil {
    toolResults[i] = message.ToolResult{
        ToolCallID: toolCall.ID,
        Content:    fmt.Sprintf("Tool execution failed: %v", toolErr),
        IsError:    true,
    }
    // Don't break - continue to generate results for remaining tools
}

Or in convertMessages() in anthropic.go, filter out incomplete tool calls when reconstructing messages.

Impact

  • Session becomes unusable after any tool abort
  • User must start a new session, losing conversation context
  • Particularly problematic for long sessions with valuable context

Workaround

Start a new session. The corrupted session cannot be recovered without manually editing the stored message files.


I'd like to work on this fix if that's okay. Happy to submit a PR.

Activity

  1. github-actions commented on Jan 14, 2026

    @github-actions
    Contributor

    This issue might be a duplicate of existing issues. Please check:

    These all report the identical Anthropic API validation error: 'tool_use ids were found without tool_result blocks'. Your detailed analysis in #8312 provides excellent root cause context for what appears to be a systemic issue with how tool execution errors and aborts are handled in message reconstruction.

    Feel free to ignore if your specific case differs, but these appear to be manifestations of the same underlying problem.

  2. popododo0720 commented on Jan 14, 2026

    @popododo0720
    Author

    Closing as duplicate of #2720. My root cause analysis may be helpful - the issue is in agent.go where aborted tool calls don't generate tool_result messages.

  3. cjmayoral commented on Feb 11, 2026

    @cjmayoral

    I also saw Tool execution aborted with {} input (edit tool), and the message ended with finish: "length". That suggests a truncated tool call can create an aborted tool entry; if tool_result is missing, it could still corrupt the session as described here. I have sanitized snippet JSONs if needed.

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