Blog
Why Agent Loops Break, and How to Fix Them
Agent loops fail in a small number of predictable ways, and most teams find each one the hard way: in production, after the loop has already burned a budget or shipped something broken. Runaway iteration, false "done" signals, degrading context, and a review step nobody built all show up as the same symptom: an agent that seemed to work in the demo and doesn't in the wild. This is a field guide to the four failure modes and the fixes that actually hold up, ending with the one bottleneck that no amount of better prompting solves: the human checkpoint.
1. Runaway loops: no stop condition
A loop that can plan, act, and observe can also do all three forever. The failure isn't dramatic: it's a loop that keeps calling the same tool with slightly different arguments, re-reading a file it already read, or retrying an action that fails the same way every time, until someone notices the token bill or the CI job that never returns.
The fix is three separate ceilings, not one:
- **Max iterations.** A hard cap on plan-act-observe cycles, set low enough that a human notices a stuck loop before it notices the invoice. Ten to twenty is a reasonable starting range for a coding loop; tune down for anything that touches production data. - **Token ceiling.** Independent of iteration count, because a single iteration can blow a context window on its own (a bad grep, a huge file read, a tool that returns an unbounded log). Track cumulative tokens per loop run and kill it when the ceiling hits, not just when iterations run out. - **Action dedup.** Hash the (tool, arguments) pair for every action the agent takes. If the same action fires twice in a row, or three times in a window, that's not persistence: it's a stuck loop, and it should trip a breaker before it trips a ceiling.
None of this is exotic. It's the same pattern you'd apply to any retry logic: the mistake is treating an agent loop as different from a retry loop just because the decision-making step is a model call instead of an if-statement.
2. Overconfident termination: the loop says done when it isn't
The mirror-image failure is worse, because it's silent. The loop doesn't run away: it stops, reports success, and the output is wrong. This happens because the agent that does the work is also the agent that judges the work, and a model grading its own output has every incentive (explicit or not) to call it finished.
Two fixes, and they compose:
- **A separate verifier subagent.** Don't let the implementing agent decide when it's done. Hand the claim to a second agent (fresh context, narrower job) whose only task is to check the specific claim being made: does this function have the signature the spec asked for, does this endpoint return the shape the caller expects. A verifier with a narrow job is much harder to fool than an implementer asked to grade its own homework. - **Hard, checkable conditions.** Wherever possible, replace "the agent thinks it's done" with a condition a script can check: zero failing tests, a lint pass, a specific string present in output, a screenshot diff under a threshold. Soft conditions ("the code looks correct") always regress toward false positives under time pressure. Hard conditions don't negotiate.
The catch: hard conditions only catch what you thought to check. A loop can pass every test you wrote and still ship a UI that's technically correct and unusable. That gap doesn't close with more tests: it closes with a human looking at the running thing, which is failure mode four.
3. Context rot in long loops
Every iteration adds to the context: the original task, prior plans, tool output, error messages, retries. None of that goes away by default, and a model's ability to weigh any one fact against the rest degrades as the pile grows, well before you hit the actual context window limit. A loop on iteration twelve is working with a context window that's mostly its own exhaust.
The symptoms are specific enough to watch for: the agent re-reads a file it already has in context, contradicts a decision it made three turns ago, or starts treating an early error message as still-current when it was fixed six iterations back.
Two mitigations, used together:
- **Fresh subagent context per phase.** Instead of one agent accumulating context across the entire loop, split the loop into phases (plan, implement, verify) and hand each phase to a subagent that starts clean, given only the artifacts it needs, not the full transcript of how it got there. This is the same idea as a verifier subagent from failure mode two, generalized: narrow context in, narrow output out. - **Compaction.** For loops that can't be cleanly phased, periodically summarize the history into a compact state (what's been tried, what worked, what's still open) and discard the raw transcript. Compaction is lossy on purpose: the loss is the point, because the alternative is a context window that's 80% noise by iteration ten.
Neither of these is free. Fresh subagents lose implicit context that sometimes mattered; compaction loses detail that occasionally turns out to be relevant three turns later. The trade is worth it anyway, because the failure mode you're avoiding (a loop quietly getting worse with every turn) is harder to detect than either of these costs.
4. The review bottleneck
The first three failure modes are solvable inside the loop: ceilings, verifiers, compaction. The fourth isn't, because it isn't a loop problem: it's a review problem, and a loop that runs faster just moves the bottleneck instead of removing it.
Here's the shape of it. A loop that ships ten iterations a day multiplies output tenfold, but the step where a human decides "this is right" doesn't scale with the loop. It scales with the human. If review used to happen once a day on one build, it now needs to happen ten times a day on ten builds, and it still needs a person who understands the product, not a linter.
Most teams solve this by not solving it: the human reviews less often, later, on more accumulated changes. That's how a loop that seemed to work in isolated bursts produces something unrecognizable after a week unattended, not because any single iteration was catastrophic, but because nobody was checking often enough to catch the drift.
The fix isn't a better prompt for the agent. It's a checkpoint that fits the pace of the loop: fast enough for a human to actually do it every iteration, and structured enough that the next iteration can act on it without a person re-typing the feedback into a prompt.
This is where Patchrooms fits. Embed one script tag on the preview the loop just produced, and a reviewer (no account needed, free and unlimited) clicks the element that's wrong and either types or speaks a comment. Patchrooms captures the DOM selector, a screenshot, the page URL, viewport, browser, and any console errors alongside the comment. That report becomes agent-ready feedback: "Copy agent feedback" produces a Markdown block with the selector, the goal, and constraints, ready to paste into Claude Code, Cursor, or whatever built the artifact. An MCP server lets the loop itself read reports and close them once fixed, so the checkpoint plugs directly into the next iteration instead of sitting in a Slack thread waiting for someone to translate it.
Others show feedback to a person. The point of putting a checkpoint here is that the loop's next iteration reads it as an instruction, not a message.
A pre-flight checklist
Before you trust an agent loop with anything that matters, check it against all four:
- Does it have a max-iteration cap, a token ceiling, and action dedup: three separate limits, not one? - Does something other than the implementing agent decide when the task is done? - Are the "done" conditions hard and checkable, or soft and self-reported? - Does context get refreshed or compacted across long runs, or does every iteration inherit the full history? - Is there a human checkpoint that happens on every iteration, not once a week, and does that checkpoint produce something the next iteration can act on directly?
The first four are solved with code you write once. The fifth is solved with a review layer that fits the pace of the loop, which is the part most teams build last, right after the loop has already shipped something they had to clean up by hand.
FAQ
- What's the single most common reason agent loops fail?
- No stop condition. Teams wire up a plan-act-observe cycle, watch it work on the demo case, and ship it without a hard ceiling on iterations, tokens, or actions. The loop runs fine until it hits an input the demo never covered, then it either spins until the budget alarm fires or quietly declares victory on broken output.
- Is context rot the same thing as running out of context window?
- No. Context rot happens well before you hit the token limit. A model's attention to any single fact degrades as the surrounding context fills with tool output, retries, and stale plans. You can have 60% of the window free and still get worse decisions than turn one, because the signal is diluted, not absent.
- Can a verifier subagent fully replace human review?
- For narrow, checkable claims, yes; a verifier that runs the test suite and great, an agent that says 'done' when tests are green is checking a fact, not an opinion. It can't replace human review, because plenty of failure modes never trip a test: a form that's technically functional but ugly, copy that's off-brand, a flow that's confusing. Those need a person looking at the running app.
- Where should the human checkpoint sit in an agent loop?
- After the agent believes it's done, before the next iteration starts. Putting it earlier wastes the reviewer's time on half-finished work; putting it later means the loop has already burned budget iterating past a wrong turn. One checkpoint on a live preview, right before the next planning step, catches issues while they're still cheap to fix.
- What does 'agent-ready feedback' mean, concretely?
- Feedback the next loop iteration can consume without a human translating it first: a DOM selector for exactly what was clicked, the page URL and viewport, a screenshot, and the comment, packaged as a Markdown block an agent can read as an instruction rather than a person having to paraphrase a Slack message into a prompt.
- Do I need a full observability stack to catch these failure modes?
- Not to start. Iteration counters, a token ceiling, and an action-dedup check cover runaway loops with a few lines of code. Overconfident termination needs a verifier step, not new infra. Context rot needs a compaction or fresh-subagent pattern in your orchestration code. The review bottleneck is the one gap that needs a dedicated tool, because it requires a UI a non-technical reviewer can use on a live page.