# Tool call loop: check the result round trip

## Symptom
`stop_reason` is `tool_use` every turn and the assistant emits the same `tool_use` block repeatedly, never progressing to an answer.

## Confirm the cause
Inspect the last user message your loop sent. For each `tool_use` block the model emitted, there must be exactly one `tool_result` block with the matching `tool_use_id`, inside a user message. The usual breaks: the executor crashed and the loop sent an empty user message, the id was regenerated instead of copied, or results were batched into the wrong turn. Without a valid result the model has no new information, so it asks again.

## Fix
1. One `tool_result` per `tool_use`, ids copied verbatim, all in the next user message.
2. On executor errors, still send a `tool_result` with `is_error` true and the error text; a missing result is worse than an error result.
3. Add a loop guard: cap consecutive tool turns (e.g. 10) and surface the transcript when it trips instead of looping forever.

## Verify
One turn completes the cycle: tool_use out, matching tool_result back, and the next assistant message moves forward or ends the turn. The docs' Tool Runner in the SDKs does this round trip for you if you keep hand-rolling it wrong.