Guide · Agents & Orchestration
How do you stop an agent loop that won't finish?
Published 1 August 2026
An agent that will not stop is the most common way an agent fails in production. It is not usually an infinite loop in the software sense — the agent is making calls, producing output and looking busy. It just never decides it is done. Fixing that is a design problem, and the fix is almost never "add a better instruction".
The four non-termination patterns
- No success criterion. The agent was told what to do and never told what finished looks like, so it keeps improving. Symptom: increasingly cosmetic changes to work that was already correct.
- Retry ping-pong. A step fails, the agent retries with a small variation, it fails again for the same underlying reason. Symptom: near-identical tool calls with slightly different arguments, and an error message that never changes.
- Goal drift. Each step spawns a new subgoal. Fixing the test reveals a lint error, which reveals a config question. Symptom: the current activity is unrelated to the original task and every step is individually defensible.
- Verification it cannot pass. The success check is impossible or unobservable — a test that needs a service that is down, a criterion the agent has no tool to measure. Symptom: the agent keeps declaring near-success and trying again.
Identify which one you have before changing anything. The remedies are different and applying the wrong one just moves the stall.
Termination conditions worth having
A durable agent has several, checked by your code and not by the model:
- Success, defined observably. A command exits zero. A schema validates. A row exists. If success cannot be observed by code, the agent has no way to stop being right.
- Step budget. A hard maximum number of iterations. This is the backstop that turns an unbounded failure into a bounded one, and every loop should have it.
- Token and cost budget. Independent of step count, because one step can read a 200k-token file.
- Wall-clock deadline. Independent again, for anything user-facing.
- No-progress detection. Stop when the last N steps produced no change in observable state — same error text, same files, same tool arguments. This is what catches retry ping-pong, and nothing else does.
- Explicit give-up path. A "blocked" outcome the agent is allowed to choose, with a reason. Without it, the only available action is to try again.
Stopping well, not just stopping
A hard cap that returns nothing is barely better than a hang. When a limit fires, the run should end with a usable artefact: what was achieved, what was left, the last error verbatim, and the single next step. That turns an exhausted budget into a handoff someone can act on — and it makes the difference between "the agent failed" and "the agent got three of five files done and is blocked on a zero-decimal currency case".
Also distinguish the exits in your telemetry. "Completed", "budget exhausted", "no progress" and "blocked by design" are four different outcomes. Collapsing them into failure destroys the signal you need to tune the loop.
Per-pattern remedies
- No success criterion: write the criterion as a command or a check, put it in the task, and require the agent to run it before claiming completion. "Done" means the check passed, not that the model is satisfied.
- Retry ping-pong: cap retries per distinct error signature, not per step. On the second identical error, stop and escalate — the third attempt has never once been the one that worked.
- Goal drift: keep the original goal pinned in standing context and require any new subgoal to be justified against it. Better still: forbid scope expansion and have the agent report the discovered issue instead of fixing it.
- Unpassable verification: make the agent report the verification result each step, so an unobservable check surfaces as "cannot run" rather than as endless effort.
A worked example
A code agent tasked with "make the test suite pass" ran for ninety steps. The log showed the same failing assertion from step 12 onward, with cosmetic edits between attempts. The underlying cause was an environment variable missing in the test runner — nothing the agent could fix from inside the repository.
Three changes ended that class of run. A no-progress rule: if the failing test names and error text are unchanged for three consecutive steps, stop. A blocked outcome the agent could choose, with a required reason field. And a step cap of twenty-five with a written handoff on exhaustion. The next occurrence terminated at step four with "blocked: DATABASE_URL not set in the test environment" — the correct answer, reached at a fraction of the cost — four steps instead of ninety. The saving is real but not linear in step count: with prompt caching each additional step mostly re-reads a cached prefix and pays full price only for the newly appended turn, so late steps cost less than early ones. Cutting ninety steps to four saves far more than a twentieth of the bill in latency and operator attention, and somewhat less than that in tokens.
The opposite failure
Termination can also fire too early: an agent that stops at the first ambiguity is useless in a different way. The balance comes from making the stop conditions specific rather than tight. A generous step budget with sharp no-progress detection outperforms a stingy step budget with none, because the first stops when the work has genuinely stalled and the second stops when the work was merely long.
Review checklist
- Can code observe success, or only the model?
- Is there a step budget, a token budget and a deadline — all three?
- Do you detect no-progress, and on what signal?
- Can the agent choose to be blocked, with a reason?
- When a limit fires, does the run leave behind an actionable handoff?
- Are the exit reasons distinguishable in your logs?
Where this fits
Loop termination sits in the Agents part of the track, alongside run modes and failure recovery. The judgement being tested is where the stop decision lives: an agent that decides for itself when it is done is an agent without a definition of done.
Related in this track
Keep going
- Agents & Orchestration track — the full module list this guide belongs to.
- Practise this with the coach — a Socratic session with Agents & Orchestration preselected.