# Error recovery needs a stopping rule

2025-08-29

Feeding a stack trace back to the model can unstick a call. Doing it forever is how agents spin.

Self-healing is real for short tasks. The model calls a tool, the tool throws, a readable error goes back into the window, the next call is better. Dex Horthy's [factor 9](https://github.com/humanlayer/12-factor-agents/blob/main/content/factor-09-compact-errors.md) is that loop, and you can ship it without adopting the other eleven. Reading of [12-factor agents](https://github.com/humanlayer/12-factor-agents). The guide is [CC BY-SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/).

## Put the error in the thread, then decide

The sketch is a while loop. Determine next step. Try it. On failure, append a formatted error and loop. On success, reset a consecutive-error counter.

Horthy mentions a cap around three tries on the same tool. That is an example, not a threshold I would copy blindly. The rule I want is some deterministic condition that ends the retry. Consecutive failures. Same error twice. Budget gone. Then you compact the window, strip the failed events, or [hand it to a human](/log/approval-before-the-side-effect). You do not keep stuffing stack traces in until the model invents a third way to call the broken endpoint.

Raw errors are often the wrong shape. Factor 3 still applies. You can rewrite the failure into something the model can use, or drop earlier turns that are now noise. Factor 8 still applies. The switch statement can take over. Factor 10 still applies. A small agent has fewer ways to spin.

## What compact is for

If you dump a full exception with a 200-line traceback, you pay for tokens and you bury the cause. Format it. Tool name, input, message, maybe a hint you already know, like unknown customer id. A looping agent wastes money. Worse, it produces a thread nobody wants to audit.

Errors are events. They are allowed in the window. Retries have a stop: count, budget, or escalate. After the stop, rewrite context or return to a person. Do not hope.

This was the last of five notes on Horthy's guide. Start at [your agent does not need to own the workflow](/log/agent-does-not-own-the-workflow) if you jumped in late.

Prev: [human approval belongs before the side effect](/log/approval-before-the-side-effect).
