Skip to content

Claude code execution: 400 on multi-turn (code_execution_tool_result.citations: Extra inputs are not permitted) #8687

Description

@vishalr15

Description

A conversation that uses Claude's code execution tool fails on the second (and later) turn with an Anthropic 400:

400 - messages.N.content.M.code_execution_tool_result.citations:
      Extra inputs are not permitted

The first turn succeeds; the error only appears once the prior assistant response is replayed as input.

Root cause

Anthropic emits a citations field on code_execution_tool_result blocks but rejects it on input (the output and input schemas differ). agno preserves server-tool result blocks for history reconstruction:

# agno/models/anthropic/claude.py
server_tool_blocks.append(block.model_dump())   # model_dump() keeps `citations`
...
model_response.provider_data.setdefault("server_tool_blocks", []).extend(server_tool_blocks)

On the next turn format_messages replays those stored blocks verbatim:

# agno/utils/models/claude.py
for block_dict in message.provider_data["server_tool_blocks"]:
    ...
    content.append(block_dict)   # `citations` echoed back as input -> 400

Because the Messages API is stateless, the whole prior response is re-sent every turn, so the illegal field is rejected before the request reaches the model.

Steps to reproduce

  1. Create a Claude agent with skills / code execution enabled.
  2. Send a message that triggers code execution (turn 1) — succeeds.
  3. Send any follow-up in the same conversation (turn 2) — 400 with the error above.

Expected

Server-tool result blocks should be replayable across turns; output-only fields Anthropic rejects on input should not be echoed back.

Environment

  • agno: 2.6.x (reproduced against main)
  • Provider: Anthropic (Claude), code execution / skills

Proposed fix

Strip the output-only citations field from code_execution_tool_result / bash_code_execution_tool_result blocks at capture time (so it's never persisted), with a matching strip at the replay point for already-persisted history. The citation data is preserved separately in ModelResponse.citations. PR to follow.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions