Cost
A stalled loop pays for every turn until the limit. OWASP lists unbounded consumption as a top risk for language model applications. A repeat check ends the waste sooner than the limit.
Home · Agents · 10 · Failure modes
Concept card · Agents
What this gets you. Read a run's trace, name how the loop went wrong, and add the stop or check that ends it.
Next on this goal: Agent evaluation.
Failure modes are the repeatable ways an agent loop goes wrong: it never stops, repeats an act, reads an error as a result, takes a result as an order, or says it's done when it isn't.
Oct 29: Practice now has three scripted traces. Name the failure, pick the first fix, then check one of your own runs.
Oct 26: OWASP sources now point to the 2026 list, where some entries have new numbers. Oct 25: First card. Two made-up traces show a stall and a ticket filed twice, each with its first fix.
Spot why your agent got stuck or did a thing twice, and know the first fix to try.
From Agent loop: name the three stops you write first.
Done, a turn limit, and a failure limit.
Each failure leaves a mark in the run's trace, the list of turns, tool calls and results. Anthropic's Building effective agents says it's common to add stopping conditions, such as a maximum number of iterations, to keep control. The OpenAI Agents SDK raises an error when a run passes its turn limit. A limit ends a bad run. It doesn't tell you why it went bad. That's what the trace is for.
Two failures are easy to miss in a first loop. A timeout doesn't mean nothing happened. AWS's guide says a failed call may still have had its side effects, so a retry can file a second ticket. And a tool error can come back as ordinary text. The MCP spec returns it as a result marked isError.
Example: made up to show the idea.
The Support assistant from Agent loop, with the same three tools: search the docs, look up an account, file a ticket.
Customer: "Why is my invoice currency wrong?"
| Turn | Tool and input | Result |
|---|---|---|
| 1 | Search the docs: "invoice currency" | No hits |
| 2 | Search the docs: "invoice currency" | No hits |
| 3 | Search the docs: "invoice currency" | No hits |
| 4 | None | Turn limit |
The turn limit ended it, but three turns did the same thing. First fix: stop when the same tool gets the same input twice, and answer "I don't know" or hand it to a person.
Customer: "My export is missing attachments."
| Turn | Tool and input | Result |
|---|---|---|
| 1 | Search the docs: "export attachments" | export.md: "Attachments are not included in the CSV." |
| 2 | File a ticket (approved) | Timeout |
| 3 | File a ticket (approved) | Ticket #4128 |
The support queue now has #4127 and #4128. The first call worked. Only the reply was lost. First fix: send the same idempotency key on the retry. Stripe's docs say retries with the same key return the saved result instead of doing it again. If the tool has no key, look the ticket up before you file again.
A stalled loop pays for every turn until the limit. OWASP lists unbounded consumption as a top risk for language model applications. A repeat check ends the waste sooner than the limit.
A repeated act shows up for the customer: two tickets, two emails, two refunds. A false done shows up later, when nothing was filed.
OWASP's Excessive agency entry says damaging actions can follow from unexpected, ambiguous or manipulated model output. An act tool turns a loop failure into a real change.
| In the trace you see | Failure | First fix |
|---|---|---|
| The same tool and input, turn after turn | No stop | Stop on a repeat; then answer or hand off |
| An act tool twice after a timeout | Repeated act | Same idempotency key; or check before you retry |
| An error result, then a confident reply | Error read as a result | Check the error flag before the model sees it as fact |
| A step the user didn't ask for, right after a document or tool result | Result taken as an order | Treat results as data; limit tools |
| "Done" with no record in your system | False done | Check the outcome in code |
Open the trace of your last ten runs. For each tool call, note the tool, its input and whether it acts. Mark any run where the same call repeats, an act runs twice, or an error is followed by a confident reply. Add the matching fix to the loop, then run those ten again.
Retrying every failed call the same way. A read is safe to try again. An act that timed out may have happened, so retry it only with the same key, or check first.
A file-a-ticket call times out. What is the safer next step?
The trace shows "Search the docs: refund policy" on turns 1 to 4, each with no hits. Which failure is this?
Look up an account returns an error marked as one, and the agent replies "You're on the free plan." What went wrong?
Example: made up to show the idea.
Scripted, not a live model. No request is sent, and nothing leaves this page.
Each trace is one run: the turns, the tool calls, and what came back. Find the row where the run went wrong, name the failure, and pick the first fix in your loop code.
Northline Desk is a made-up support desk. Its assistant has the three tools from Agent loop: search the docs, look up an account, and file a ticket.
A turn limit ended a bad run. What tells you which fix to add?
Open the trace of one run that went wrong: your own agent, or an AI tool that shows its steps. Find the row where it went wrong. Name the failure, and write the first fix your loop needs. Then change one thing and run it again.
If a step followed text inside a tool result, that's a result taken as an order. Prompt injection → covers it.
Read the row where the run went wrong. Fix the loop there, not only the turn limit or the instructions.
Turn each failure you find into a task in your eval set: Agent evaluation →
Where the three stops come from: Agent loop →
A turn limit ends a run. The trace tells you which stop was missing, or too loose.
Keep the turn, the tool, the input, whether the tool acts or only reads, the result or the error flag, the time taken, and the stop reason. Without the input and the act-or-read flag, you can't spot a repeat or a second act.
Stop when the same tool gets the same input twice. A near-repeat, one word changed, is worth a look too. A repeat can be fine when you are polling a status page and you wait between calls.
AWS's guide says reads are usually safe to retry. Retry them with backoff and jitter: wait longer after each try, plus a small random delay. An act is different. Retry it only with an idempotency key, as in Stripe's idempotent requests, or check whether it already happened. Don't retry more times than the failure limit allows.
A repeated act that waits for a person's OK is caught by that person. You still want the key, so a second call does not file again if the first one landed.
The MCP spec returns a tool execution error as a result with isError: true. A protocol error is a different failure, and it is not a tool result. The spec says clients should pass tool execution errors to the language model so it can self-correct. Pass the error as an error, not as a fact the model can quote.
If the fix is checking what came in or what goes out, that check is a guardrail.
Two examples, in alphabetical order. Google's Agent Development Kit sets max_iterations on a loop agent. The OpenAI Agents SDK sets max_turns, raises MaxTurnsExceeded, and lets an error handler return a controlled reply. See Running agents.
Microsoft's AI Red Team (April 24, 2025) sorts agent failures into novel ones, unique to agents, and existing ones that matter more in agents because of their impact or likelihood. A loop that files twice fits the second group: filing was already possible, and the loop made it easy to repeat.
Each failure you find becomes a task in your eval set. Agent evaluation is where you grade that set.
Which two trace fields do you need to spot a repeated act?
The input, and whether the tool acts or only reads. Without them, two File a ticket calls look like any two turns.