← All posts
·5 min read

5 LLM agent failure modes in production

Tool-use loops with no exit, hallucinated arguments, state leakage, over-confident planning, retry storms — five failures I keep seeing, and what stops each.

Anti-pattern posts get shared because they're specific, and specific is what most agent advice isn't. These are five failure modes I keep seeing in production agents — not theoretical, the shape each one actually takes when it happens, and what stops it.

Who this is for: an engineer whose agent works in every demo and has started doing something strange in production that the demo never showed.

None of these five look like a bug in the code that failed. They look like the agent working, slightly wrong, until the bill or the complaint arrives.

Tool-use loops with no termination condition

An agent calls a tool, doesn't like the result, calls it again with a slight variation, and keeps going — because nothing in the loop asks "have I tried this enough times." The failure doesn't look like an error; it looks like the agent working hard on something, right up until the token count or the bill makes it obvious.

The fix is a hard cap on tool calls per turn, set low enough to hurt, plus a rule that a repeated call with near-identical arguments counts against the cap even if the wrapper thinks it's a new attempt. An agent that hits the cap should say so, not fail silently — a visible "I couldn't resolve this in the allowed attempts" is a feature, not a degraded response.

Hallucinated tool arguments

The model calls a real tool with an argument that looks plausible and isn't — an ID that doesn't exist, a date outside any valid range, a field name close to but not the schema's actual field name. The tool call succeeds at the API level and fails at the semantic level, which is the dangerous combination: nothing errors, so nothing alerts.

Type-check every argument against the tool's actual schema before execution, not just its shape but its domain — an ID gets looked up and confirmed to exist before the call that uses it runs, not after. This is more validation than the framework gives you by default, and it's the validation that catches the failures that matter, because a malformed argument is easy to catch and a plausible-but-wrong one is exactly what type-checking against shape alone will let through.

State leakage across conversation turns

Something from turn three — a value, an assumption, a partially-completed action — is still influencing turn seven, after the context that made it valid has changed. This is the failure mode that's hardest to reproduce, because it depends on conversation history that looks fine at each individual step.

A prompt is an interface, and state carried silently across turns is the interface changing underneath the conversation without anyone deciding it should. The fix is treating turn-scoped state as explicit — logged, and cleared deliberately rather than left to fall out of context naturally — which is the same discipline an audit trail needs for an entirely different reason: you can't debug what you didn't record changing.

Over-confident planning that ignores constraints

The agent produces a plan that's internally coherent and violates a constraint it was explicitly given — a budget, a permission boundary, a business rule — because planning and constraint-checking happened as one step instead of two. The model is good at producing plausible plans and not reliably good at checking its own plan against a hard rule at the same time it's generating it.

Separate the two. Generate the plan, then validate it against constraints as a distinct, non-negotiable step the model doesn't get to skip or reason its way around — the same isolation-inside-the-query principle that RAG needs for permissions applies here to business rules: enforce it in code, not in the prompt asking nicely.

The retry storm

One transient failure — a timeout, a rate limit — turns into ten calls instead of one, because retry logic has no backoff, no jitter, and no shared awareness that every other in-flight request just hit the same failure at the same time. This is the failure mode that turns a five-minute provider blip into a cost spike and a support queue.

The signal that you have this failure mode, before it becomes an incident: chart your provider-call rate against your legitimate request rate. A retry storm shows up as a spike in the first that has no matching spike in the second — calls multiplying without any corresponding increase in real traffic.

Exponential backoff with jitter is the known fix; the part teams skip is a circuit breaker that stops the whole class of retries once the failure rate crosses a threshold, rather than each request independently deciding to try again.

What ties all five together

None of these look like a bug in the code that failed — that's what makes them agent failure modes specifically, rather than ordinary software bugs. Each one is the agent doing something locally reasonable that's globally wrong, and each fix is the same shape: a hard boundary enforced outside the model's own judgment, because the model's judgment is exactly the thing that failed.

If your agent is doing something in production that the demo never showed, that's usually where I start looking — though sometimes the answer isn't fixing the agent, it's asking whether the task needed one.

Shanker Dhand
Shanker Dhand
AI Engineer & Technical Lead

I design and ship production AI systems — RAG pipelines, agents, and evaluation infrastructure — built on 10+ years of full-stack engineering.

Related posts