zeroclaw-labs/zeroclaw · error
Agent exceeded maximum tool iterations ({max_iterations})
Error message
Agent exceeded maximum tool iterations ({max_iterations}) What it means
When the tool loop exhausts max_iterations and LoopKnobs.max_iteration_behavior is ErrorAtCap, finish_after_max_iterations bails immediately with this error instead of spending one more LLM call on a graceful summary — embedders driving Agent::turn use it as a control signal ('cap reached'). The graceful path (a tools-free final summary) only runs under the non-ErrorAtCap behavior. A WARN 'tool_loop_exhausted' event with the model and cap is logged first.
Source
Thrown at crates/zeroclaw-runtime/src/agent/turn/max_iter.rs:48
mut new_messages_out: Option<&mut Vec<ChatMessage>>,
) -> Result<String> {
::zeroclaw_log::record!(
WARN,
::zeroclaw_log::Event::new(module_path!(), ::zeroclaw_log::Action::Fail)
.with_category(::zeroclaw_log::EventCategory::Agent)
.with_outcome(::zeroclaw_log::EventOutcome::Failure)
.with_attrs(::serde_json::json!({
"model": model,
"max_iterations": max_iterations,
"trace_id": turn_id,
})),
"tool_loop_exhausted"
);
// ErrorAtCap callers (embedders driving Agent::turn) treat the cap as a
// control signal: bail instead of spending another LLM call on a summary.
if knobs.max_iteration_behavior == MaxIterationBehavior::ErrorAtCap {
anyhow::bail!("Agent exceeded maximum tool iterations ({max_iterations})")
}
// Graceful shutdown: ask the LLM for a final summary without tools
::zeroclaw_log::record!(
WARN,
::zeroclaw_log::Event::new(module_path!(), ::zeroclaw_log::Action::Note)
.with_category(::zeroclaw_log::EventCategory::Agent)
.with_outcome(::zeroclaw_log::EventOutcome::Unknown)
.with_attrs(::serde_json::json!({"max_iterations": max_iterations})),
"Max iterations reached, requesting final summary"
);
let tool_calls_stripped =
crate::agent::history_pruner::strip_orphaned_tool_calls_from_assistants(history);
let tool_messages_removed =
crate::agent::history_pruner::remove_orphaned_tool_messages(history).removed;
if tool_calls_stripped > 0 || tool_messages_removed > 0 {
::zeroclaw_log::record!(
WARN,View on GitHub (pinned to 88bb9c8533)
Solutions
- Raise max_iterations for tasks that legitimately need more tool rounds.
- If you want a final answer instead of an error at the cap, set the max-iteration behavior to the graceful summary path.
- Inspect the loop logs for non-convergence: repeated identical tool calls or failing tools burning iterations, and fix the underlying tool/prompt issue.
- For embedded use, catch this error and treat it as 'budget exhausted' — resume the turn with a fresh budget if the work should continue.
Example fix
// before — embedder default treats the cap as a hard error let result = agent.turn(request).await; // bails: exceeded maximum tool iterations // after — opt into graceful summary at the cap, or raise the cap // knobs: max_iteration_behavior = MaxIterationBehavior::Graceful (summary instead of error) // or: max_iterations = 80
Defensive patterns
Strategy: fallback
Try / catch
Catch 'Agent exceeded maximum tool iterations', then choose a fallback: resume the turn with a raised cap if the work should continue, or accept the accumulated transcript/streamed output as partial results. Under ErrorAtCap this error is a control signal — treat it as 'budget exhausted', not a crash.
Prevention
- Size max_iterations to the task (repo-wide work needs more than chat-scale defaults)
- Watch per-turn iteration counts and alert near the cap
- Fix non-convergent loops (repeated failing tool calls) instead of only raising the cap
- Pick the max-iteration behavior deliberately when embedding Agent::turn
When it happens
Trigger: A task legitimately needs more tool rounds than the configured cap; the model loops without converging (repeated failing tool calls); an embedded Agent::turn integration running with the default ErrorAtCap behavior on long multi-step jobs.
Common situations: Large refactors or repo-wide scans under a default iteration cap; a tool returning errors so the model keeps retrying; embedders unaware that ErrorAtCap turns the cap into a hard error.
Related errors
- Agent loop aborted: repeated prompt-required tool call '{too
- Invalid Azure OpenAI tool specification: unsupported tool ty
- Ollama returned non-prompt-guided tools payload while native
- Invalid OpenAI tool specification: unsupported tool type '{}
- Final summary LLM call timed out after {step_secs}s (step_ti
AI-assisted analysis of zeroclaw-labs/zeroclaw@88bb9c8533 (2026-08-23).
Data as JSON: /api/errors/72747f065c9a2722.
Report an issue: GitHub.