Skip to content

fix(claude): drop invalid tool history before upstream#4577

Open
yinkev wants to merge 1 commit into
router-for-me:devfrom
yinkev:fix/claude-orphan-tool-history
Open

fix(claude): drop invalid tool history before upstream#4577
yinkev wants to merge 1 commit into
router-for-me:devfrom
yinkev:fix/claude-orphan-tool-history

Conversation

@yinkev

@yinkev yinkev commented Jul 25, 2026

Copy link
Copy Markdown
Contributor

Fixes #4112.

Problem

Anthropic rejects stale or malformed Claude message history when:

  • an assistant tool_use has no matching result in the immediately following user message;
  • a user tool_result references no tool call in the previous assistant message; or
  • a tool_result appears after text or image content instead of in the leading result block group.

The existing Claude-upstream sanitizer removed incompatible reasoning signatures but forwarded those structurally invalid tool blocks unchanged, producing HTTP 400 before model execution.

Change

Enable tool-history repair only in SanitizeClaudeMessagesForClaudeUpstream:

  • pair assistant tool calls with leading results in the immediately following user message;
  • preserve valid parallel tool calls and allow their results in any order;
  • remove unmatched calls, stale results, blank IDs, wrong-role tool blocks, and results appearing after non-result content;
  • remove messages left empty by that repair;
  • retain the existing signature sanitizer behavior and preserve an unchanged payload without copying it when history is already valid.

Other provider compatibility paths keep their existing behavior because the new option is disabled by default.

Verification

  • red/green sanitizer regressions for orphan calls/results, late results, partial parallel matches, and valid parallel history;
  • outbound ClaudeExecutor regression confirming invalid blocks are absent from the Anthropic request body;
  • existing Claude signature logging fixture updated to use valid paired tool history;
  • go test ./internal/signature ./internal/runtime/executor -count=1;
  • focused go test -race for the sanitizer and Claude executor paths;
  • go vet ./internal/signature ./internal/runtime/executor;
  • required go build -o test-output ./cmd/server && rm test-output;
  • git diff --check.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 82ef4be747

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread internal/signature/claude_messages_sanitize.go Outdated
@yinkev
yinkev force-pushed the fix/claude-orphan-tool-history branch from 82ef4be to a93e8f3 Compare July 26, 2026 02:19

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: a93e8f3476

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread internal/signature/claude_messages_sanitize.go Outdated
@yinkev
yinkev force-pushed the fix/claude-orphan-tool-history branch from a93e8f3 to a0081b9 Compare July 26, 2026 02:36

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: a0081b93e6

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread internal/signature/claude_messages_sanitize.go Outdated
@yinkev
yinkev force-pushed the fix/claude-orphan-tool-history branch from a0081b9 to 8b1a108 Compare July 26, 2026 02:46

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 8b1a108174

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread internal/signature/claude_messages_sanitize.go
@yinkev
yinkev force-pushed the fix/claude-orphan-tool-history branch from 8b1a108 to 7cc7ee5 Compare July 26, 2026 02:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant