# Failure modes

> 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.

Read a run's trace, name how the loop went wrong, and add the stop or check that ends it.

Track: Agents
Card: https://buildsparkai.com/failure-modes
Plain text: https://buildsparkai.com/failure-modes.md
Last checked: 2026-10-25

## What it is

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.

## Why it matters

**Cost.** A stalled loop pays for every turn until the limit. [OWASP](https://genai.owasp.org/resource/owasp-genai-llm-top-10-2026/) lists unbounded consumption as a top risk for language model applications. A repeat check ends the waste sooner than the limit.

**Quality.** A repeated act shows up for the customer: two tickets, two emails, two refunds. A false done shows up later, when nothing was filed.

**Risk.** [OWASP's Excessive agency entry](https://genai.owasp.org/resource/owasp-genai-llm-top-10-2026/) says damaging actions can follow from unexpected, ambiguous or manipulated model output. An act tool turns a loop failure into a real change.

## Try today

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.

## Common mistake

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.

## Self-check

A file-a-ticket call times out. What is the safer next step?

Retry with the same key, or look the ticket up

## Understand it: read the trace, then stop the next one

6 min, optional

A turn limit ends a run. The trace tells you which stop was missing, or too loose.

### The trace fields you need

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.

### Repeat checks

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.

### Retries

[AWS's guide](https://builder.aws.com/content/3EumjoZascWd1oZiEgL8ORlv3qE/timeouts-retries-and-backoff-with-jitter) 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](https://docs.stripe.com/api/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.

### Errors as results

The [MCP spec](https://modelcontextprotocol.io/specification/2026-07-28/server/tools) 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](/guardrails).

### Turn limits in frameworks

Two examples, in alphabetical order. Google's Agent Development Kit sets `max_iterations` on a [loop agent](https://adk.dev/agents/workflow-agents/loop-agents/). The OpenAI Agents SDK sets `max_turns`, raises `MaxTurnsExceeded`, and lets an error handler return a controlled reply. See [Running agents](https://openai.github.io/openai-agents-python/running_agents/).

### New with agents, or made worse

[Microsoft's AI Red Team](https://www.microsoft.com/en-us/security/blog/2025/04/24/new-whitepaper-outlines-the-taxonomy-of-failure-modes-in-ai-agents/) (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.

### From failure to test

Each failure you find becomes a task in your eval set. [Agent evaluation](/agent-evaluation) is where you grade that set.

### Check yourself

**Which two trace fields do you need to spot a repeated act?**

Answer:

The input, and whether the tool acts or only reads. Without them, two File a ticket calls look like any two turns.

## Practice and deep

Example: made up to show the idea.

Scripted, not a live model. No request is sent, and nothing leaves this page.

Three traces. Name the failure, then fix the loop.
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.

1 of 3 · Worked
Customer: "How long is the refund window?"

Scripted trace · 4 turns

- Turn 1 · Search the docs: "refund window" → No hits

- Turn 2 · Search the docs: "refund window days" → No hits

- Turn 3 · Search the docs: "refund window policy" → No hits

- Turn 4 · No tool → Turn limit

Read first: the tool and input on each turn. Same tool, one word changed each time, and the same result.

Failure: No stop. The turn limit ended the run, but turns 2 and 3 added nothing.

First fix: make your repeat check count a near-repeat too, the same tool with one word changed. Stop at turn 2, then reply "I couldn't find that in the help pages" or hand it to a person.

Why: a higher turn limit gives the loop more room to repeat. A lower one ends the run sooner but still doesn't say which step stalled. The repeat check does both.

2 of 3 · Your turn
Customer: "When does my plan renew?"

Scripted trace · 3 turns

- Turn 1 · Search the docs: "plan renewal" → billing.md: "Your renewal date is on your account page."

- Turn 2 · Look up an account: the customer's email → isError: true · "Account service unavailable"

- Turn 3 · Reply → "Your plan renews on 1 November."

Read first: the result on turn 2, then the date in the reply. Where did the date come from?

What's the first fix in your loop?

A · No stop: add a repeat check to Look up an account
B · Repeated act: send the lookup again with an idempotency key so it can't run twice
C · Error read as a result: check the error flag before the reply uses it

## Sources

- [Amazon Web Services, Timeouts, retries, and backoff with jitter](https://builder.aws.com/content/3EumjoZascWd1oZiEgL8ORlv3qE/timeouts-retries-and-backoff-with-jitter)
- [Anthropic, Building effective agents](https://www.anthropic.com/research/building-effective-agents)
- [Google, Loop template workflow agent](https://adk.dev/agents/workflow-agents/loop-agents/)
- [Microsoft, New whitepaper outlines the taxonomy of failure modes in AI agents (published April 24, 2025)](https://www.microsoft.com/en-us/security/blog/2025/04/24/new-whitepaper-outlines-the-taxonomy-of-failure-modes-in-ai-agents/)
- [Model Context Protocol, Tools](https://modelcontextprotocol.io/specification/2026-07-28/server/tools)
- [OpenAI, Running agents](https://openai.github.io/openai-agents-python/running_agents/)
- [OWASP, OWASP GenAI LLM Top 10 2026: LLM03:2026 Excessive Agency (LLM means large language model)](https://genai.owasp.org/resource/owasp-genai-llm-top-10-2026/)
- [OWASP, OWASP GenAI LLM Top 10 2026: LLM06:2026 Unbounded Consumption (LLM means large language model)](https://genai.owasp.org/resource/owasp-genai-llm-top-10-2026/)
- [Stripe, Idempotent requests](https://docs.stripe.com/api/idempotent_requests)

Vendor, framework and standards docs, plus Microsoft's AI Red Team. The Tools specification is dated 2026-07-28. OWASP Top 10 for LLM Applications 2026 is an open community security project.
