tinyhumansai/openhuman · error · AgentError::MaxIterationsExceeded
Agent exceeded maximum tool iterations ({max})
Error message
Agent exceeded maximum tool iterations ({max}) What it means
The agent harness hit its model-call/tool-iteration cap: the run consumed more model calls than the configured maximum for the turn. tinyagents reports this as TinyAgentsError::LimitExceeded containing 'model call', which the dispatcher maps to the typed AgentError::MaxIterationsExceeded so callers can downcast it (Sentry skip) and render the canonical message — it is a policy stop, not a provider failure, so it must not surface as a leftover provider error or be reported to Sentry.
Source
Thrown at src/openhuman/agent/tinyagents/mod.rs:953
// here. Ordering the cap/depth mappings ahead of the slot is
// defense-in-depth: a run that failed on the model-call cap or a
// spawn-depth limit is not a provider error, so it must surface as
// `MaxIterationsExceeded` / the depth error rather than a leftover
// provider error (wrong classification, wrong Sentry suppression,
// wrong user message).
//
// The model-call cap (when not pausing gracefully — the channel/CLI
// path) maps to the typed `AgentError::MaxIterationsExceeded` so
// callers downcast it (Sentry skip) and render the canonical
// "Agent exceeded maximum tool iterations" message, matching the
// legacy `ErrorCheckpoint`.
if let tinyagents::TinyAgentsError::LimitExceeded(msg) = &e {
if msg.contains("model call") {
tracing::debug!(
model,
"[tinyagents] run hit the model-call cap; mapping to MaxIterationsExceeded (not consulting error_slot) — #4457 defect B"
);
return Err(anyhow::Error::new(
crate::openhuman::agent::error::AgentError::MaxIterationsExceeded {
max: max_iterations,
},
));
}
}
if let Some(depth_err) = tinyagents_depth_error(&e) {
return Err(anyhow::Error::new(depth_err));
}
// Otherwise prefer the original typed provider error (preserves
// `AgentError` downcasts the caller relies on) over the harness's
// string wrap — this is where a genuine model/provider failure that
// halted the run is re-surfaced with its real classification.
// #4469 item 3: `into_inner` recovers a poisoned slot so a panic in
// one run can't cascade into a second panic here that would mask the
// original typed provider error.
if let Some(original) = error_slot
.lock()View on GitHub (pinned to 7491200858)
Solutions
- Tighten the prompt or tool results so the task completes within the iteration cap (e.g. reduce redundant tool round-trips)
- Raise the per-turn model-call cap in the agent/harness configuration if the task legitimately needs more iterations
- If a tool is failing repeatedly and burning iterations, fix the underlying tool failure the loop is retrying around
Defensive patterns
Strategy: fallback
When it happens
Trigger: Thrown at src/openhuman/agent/tinyagents/mod.rs:953 when the library encounters an invalid state.
Common situations: See trigger scenarios.
AI-assisted analysis of tinyhumansai/openhuman@7491200858 (2026-08-17).
Data as JSON: /api/errors/6fc37373553187bd.
Report an issue: GitHub.