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

  1. Tighten the prompt or tool results so the task completes within the iteration cap (e.g. reduce redundant tool round-trips)
  2. Raise the per-turn model-call cap in the agent/harness configuration if the task legitimately needs more iterations
  3. 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.