โ† All guides
๐Ÿ›debugging

Loops Gone Wrong: Documented Agent Failures and the Guardrail Each One Teaches

Loops Gone Wrong: Documented Agent Failures and the Guardrail Each One Teaches

Every guardrail in a good harness exists because someone learned it the expensive way. This is the incident file: documented agent-loop failures, each with its primary source, and the specific control that would have contained it. No hypotheticals, no urban legends โ€” if we couldn't verify a number against the source, it's not in here.

1. The trailing `~/` that wiped a Mac

December 8, 2025. A developer posting as u/LovesWorkin asked Claude Code to clean up an old repo. It executed:

rm -rf tests/ patches/ plan/ ~/

Three project directories โ€” and a stray trailing ~/, which zsh expanded to the entire home directory. Desktop, Documents, Library, Keychain, SSH keys, years of files. On an SSD with TRIM, recovery was impossible; even Claude Code lost the ability to authenticate, because its own credentials lived in the directory it deleted. The Reddit thread passed 1,500 upvotes within hours; Docker's engineering blog published a full forensic breakdown.

It wasn't a one-off. GitHub issue #10077 documents a similar wipe on Ubuntu/WSL2 โ€” and the damning detail there is that the user was *not* running --dangerously-skip-permissions; the permission system approved a command whose expansion it didn't catch. Issue #12637 is a third mechanism: the agent had earlier created a directory literally named ~, then "cleaned it up" with an unquoted rm -rf ~.

The guardrail: never rely on the model โ€” or a single permission prompt โ€” to catch destructive shell expansion. Run loops in a worktree, container, or sandbox where ~/ is the workspace, not your life. And gate the command class itself: a PreToolUse hook that pattern-matches rm -rf, force-push, and curl | sh and denies by default. (This incident class is exactly why our ingest evaluator default-fails any submitted loop containing those commands.)

2. Four million tokens in five minutes

June 2026. Claude Code issue #68619 โ€” "Subagent spawning and subagent pattern bugs trigger infinite recursion, infinite token usage" โ€” was tagged critical by Anthropic. The report describes subagents spawning children fifty levels deep, ignoring the environment flag meant to disable forking, and one observed session where the recursive tree burned 4 million tokens in under five minutes โ€” a full Pro Max 20x five-hour budget, gone before the user could react. From the Trenches connected it to a June 2 outage traced to the same pattern: agents spawning agents in a loop that wouldn't terminate, ending in emergency refunds.

The guardrail: the platform's own loop detection is not your safety net โ€” this bug *was* the platform. You need an external kill switch that watches spend rate, not just totals: tokens-per-minute spiking or the same command repeating N times means kill the process, ask questions later. That's the watchdog pattern โ€” a second, dumber loop whose only job is stopping the first one: [runaway-bill-guardrail-loop](/loops/runaway-bill-guardrail-loop-watchdog-beside-the-worker).

3. $40 in 18 minutes โ€” the retry storm

A developer running a multi-agent loop wrote up the postmortem on dev.to: one agent got stuck retrying a malformed tool response, hammering the API until the bill alert fired. The detail that makes it instructive: he *had* per-call cost logging. What he didn't have was a shared cap โ€” each call looked cheap; the sum was the problem. His fix was a shared atomic budget across all agents, so "the next loop dies at $5 instead of $40."

The guardrail: budgets must be shared, atomic, and enforced *before* the call, not logged after it. Per-call logging is observability; a hard cap is a control. They are not the same thing. Headless runs make this easy to wire: --output-format json returns total_cost_usd per invocation โ€” sum it in the harness, exit when the ceiling's hit.

4. $4,200 over a long weekend

From a 30-team cost audit by LeanOps: a single developer at one client hit $4,200 in API fees over a long weekend during an unattended autonomous refactoring run โ€” on a workload the team hadn't validated. The mechanism isn't exotic: agents re-send accumulated context on every step, so late-loop steps cost multiples of early ones, and an unsupervised loop compounds that for three days straight. The same audit found the 99th-percentile agent user costing $4,200+/month while the median sat at $480 โ€” the spread *is* the runaway sessions.

The guardrail: wall-clock limits and daily spend cutoffs that don't care how "close" the agent thinks it is. LeanOps' recommended config is concrete: soft cap with an alert, hard daily cutoff, monthly ceiling requiring human approval. If a loop is worth running over a weekend, it's worth a timeout and a budget file.

5. Stuck is not working

The quieter failure mode: loops that burn time and tokens while making zero progress. The Cursor forum is a running catalog โ€” agents in an endless review-step loop, continuous loops, CLI loops, and a diagnostic loop instead of completing tasks. Nothing crashed. Nothing finished either.

The guardrail: no-progress detection. Diff the repo between iterations; if the delta stops changing, that's one of the four legitimate stop reasons in the OpenAI Cookbook's stop-condition taxonomy โ€” halt and hand off, don't spin.

And the flip side, so your guardrails don't become the bug: Cursor users running *legitimately* repetitive test automation get flagged as looping and halted โ€” there's a feature request to disable loop detection for exactly this. Every no-progress heuristic needs an explicit allow-flag for intentional repetition.

The guardrail checklist

Every incident above maps to a missing control. Before any loop runs unattended:

  • [ ] Sandbox the blast radius. Worktree, container, or microVM. The agent's ~/ must not be your ~/.
  • [ ] Hooks that deny by default. PreToolUse gate on rm -rf, force-push, curl | sh, secret paths. Remember the exit-code semantics: exit 2 or JSON permissionDecision: "deny" blocks โ€” exit 1 does not, and silence doesn't approve.
  • [ ] Hard budgets, enforced pre-call. Iteration cap + wall-clock timeout + shared atomic spend cap. Log total_cost_usd per run.
  • [ ] A watchdog beside the worker. Rate-based kill switch for token spikes and command repetition โ€” [the watchdog loop](/loops/runaway-bill-guardrail-loop-watchdog-beside-the-worker) is the template.
  • [ ] No-progress detection with an override flag for intentional repetition.
  • [ ] An evaluator gate the model can't argue with: default-fail, checks the diff against scope, never lets the loop grade its own homework.
  • [ ] A handoff channel. Notes to a progress file every iteration, and a ping when it stops โ€” ConnectMyEmail handles the "agent sends you an email" part so the watchdog's alert actually reaches you.

None of this is exotic. It's the same discipline ops learned decades ago โ€” supervision, budgets, circuit breakers โ€” applied to a worker that's smarter and less predictable than a cron job.

Want the checklist applied to *your* loop automatically? Paste it into [/grade](/grade) and get a safety grade with the specific missing controls flagged. Building from scratch? The [loop builder](/builder) bakes every item above into the harness it generates โ€” because the loops that make the incident file are never the ones that had budgets.

Ready to run one? Browse the loop directory โ†’