Why did our agent run for 40 minutes and produce nothing?
The agent has no step budget, no token budget, and no way to recognize it is stuck — a failing tool call stays in its context and keeps looking like a reasonable next thing to try, so it keeps trying variations of the same failed approach until something external (a timeout, a bill, a human) stops it.
Also known as runaway agent, infinite tool-call loop
What does this look like in production?
- A run's duration or token spend is an order of magnitude above the median for the same task type
- The trace shows the same tool called repeatedly with slightly varied arguments and no forward progress
- The agent eventually times out or hits a platform limit rather than reaching a terminal state on its own
- Cost per completed task has a long, expensive tail that the average masks
Why does it happen?
An agent loop keeps calling the model with the accumulated transcript and executing whatever tool call comes back, until the model decides to stop. Without an explicit budget or progress check, nothing external forces a stop, and the model has no reliable internal signal that "I have tried this six times and it keeps failing" should mean "give up or escalate" rather than "try again with slightly different arguments." The failed tool result sits in context looking exactly like fresh information, so the model reasons forward from it as if a new attempt might work.
This compounds because each additional attempt adds more failed context, which the model keeps re-reading and re-reasoning over, without a change in the actual constraint that caused the failure in the first place. Nothing in a typical agent harness distinguishes "still making progress" from "looping" — both look like ordinary next steps from the model's point of view.
How do you confirm it's this?
- Plot steps-per-run and token-spend-per-run as distributions, not averages, and look at the p99 relative to the median
- Count runs where the same tool is called with near-identical arguments more than twice in a row
- Check whether any run in your logs ended by timeout or platform limit rather than a model-issued terminal action
- Compare cost per completed task against cost per attempted task — a large gap means failed runs are eating budget without a matching signal
How do you fix it?
- Set a hard step and token budget per run
Cap the number of tool calls and total tokens a single run can consume, and force a terminal state — success, failure, or escalation — when the cap is hit, rather than letting the loop continue indefinitely.
- Deduplicate identical or near-identical calls
Detect when the agent is about to repeat a call it already made with the same effective arguments and short-circuit it, forcing a different strategy or a stop instead of a silent retry.
- Terminate or escalate after N no-progress steps
Define what "progress" means for the task (new information retrieved, a new tool used, state actually changed) and force the loop to stop or hand off to a human once several consecutive steps show none.
- Record a terminal reason on every run
Every run should end with an explicit, logged reason — succeeded, failed, budget-exceeded, no-progress-timeout — so you can measure how often each one fires instead of inferring it from a raw duration number.
What this doesn't cover
A long run is not always a broken one — some tasks genuinely need many steps. This diagnosis applies when duration or cost is disproportionate to task complexity and the trace shows repetition without new information, not simply when a run is slow.
A Ship Audit runs this full checklist against your actual system and hands back a written, prioritized plan.