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.
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-appendof 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
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 assistantmessage and the tool result), which is the pattern that works correctly.
The "Advanced usage" example is inconsistent with this.