Skip to content

[Bug] append_messages() inside tool runner loop causes infinite loop (advanced usage docs example) #1536

@Camiloez

Description

@Camiloez

Link to Advanced Usage Docs Example

Root cause

Calling runner.append_messages(user_message) inside the loop sets
_messages_modified = True, which causes __run__ to skip the auto-append
of the assistant message + tool result (line 281 of _beta_runner.py).
The next iteration sends a request with no tool result in history, so Claude
sees the original question unanswered and makes the tool call again.

Minimal repro

Compacted and consolidated from the website

from anthropic import beta_tool, Anthropic

client = Anthropic()


@beta_tool
def get_weather(location: str, unit: str = 'fahrenheit') -> str:
    return json.dumps({
        'temperature': '20°c', 'condition': 'sunny'
    })


runner = client.beta.messages.tool_runner(
    model="claude-haiku-4-5",
    max_tokens=1024,
    tools=[get_weather],
    messages=[{
        "role": "user",
        "content": "what's the weather in San Francisco?"
    }]
)


for message in runner:
    tool_response = runner.generate_tool_call_response()
    if tool_response:
        print(f"Tool result: {tool_response}")

    # increase tokens for next request
    runner.set_messages_params(
        lambda params: {
            **params,
            "max_tokens": 2048,
        }
    )

    # add additional messages
    runner.append_messages(
        {"role": "user", "content": "be concise in your response"}
    )

Expected behavior

The "be concise" user message is appended, tool results are still
auto-appended, loop terminates.

Actual behavior

Infinite loop — tool result never reaches history.

Note

The "Modifying tool results" example on the same page correctly calls
runner.append_messages(message, tool_response) (both the assistant
message and the tool result), which is the pattern that works correctly.

The "Advanced usage" example is inconsistent with this.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    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