YG Yusuf Ghyasi FOUNDER · ENGINEER
Profile 01 Agaro 03 Work 04 Doctrine 05 Research Contact
← ARCHIVE RA-008
AGENTIC AI FLAGSHIP

A Field Guide to How Agents Actually Fail

After enough production incidents, agent failures stop looking random. They cluster into a handful of shapes you can design against.

YUSUF GHYASI February 7, 2026 12 MIN READ

The first dozen times an agent failed in production, every failure felt unique. A weird one-off. A bad model day. I’d patch the specific symptom and move on. Then I’d hit a thirteenth, and a thirtieth, and somewhere in there the pattern surfaced: these were not random. The same half-dozen shapes kept recurring across completely different agents — a voice caller, an operator running a business back office, an enricher chewing through federal award data. Different domains, identical failure skeletons. Once you can name the shapes, you stop debugging incidents and start designing against categories. This is my field guide to the ones that actually show up.

1. The loop

The agent does the same thing over and over. Search, no good result, search again with a trivially different query, fail, repeat. It’s locally rational at every step and globally stuck. Each move makes sense in isolation; the agent just has no memory that it already tried this family of moves.

The loop comes from a reactive control structure with no anchor. Pure step-by-step decision-making conditions only on history, not on strategy, so nothing tells the agent “you’re going in circles.”

What I design against it:

  • A hard step cap. Non-negotiable. A looping agent is unbounded cost and zero progress, so it must hit a wall.
  • Loop detection. If the last N actions are near-identical, break out and escalate or re-plan rather than grinding.
  • An outer plan over the reactive inner work. A plan gives a definition of done that a bare loop never has, which is the structural fix, not just the bandage.

2. Hallucinated progress

The scariest one, because it’s silent. The agent reports success on work it never did. It writes a five-step plan, marches through it announcing each step complete, and produces a clean log that says everything worked — except step two actually failed and nothing noticed. You only find out when the downstream effect is missing.

This is the dark twin of the loop. Looping is over-reacting and never committing. Hallucinated progress is over-committing to a plan and performing it as a script instead of checking reality. The agent narrates the plan rather than verifying the world.

A loud failure costs you an incident. A silent failure costs you trust, because by the time you find it, you’ve already told someone it worked.

What I design against it:

  • Verify against the world, not the narration. After a step that claims to have done something, re-read the actual state. Did the record change? Did the email send? Don’t take the agent’s word.
  • A blunt per-step check: “did this achieve its stated goal — yes, no, partial?” judged from the observed result, not the agent’s own story.
  • Structured tool results the agent can’t fudge. A booking tool returns a confirmation id or an error, never a vague “done.”

3. Context poisoning

One bad fact enters early and corrupts everything after it. A hallucinated entity id, a misparsed number, a stale value — it lands in the context and becomes the false premise of every subsequent step. The agent then reasons flawlessly from a wrong foundation. The reasoning looks great. The output is garbage, and it’s garbage in a way that’s hard to spot because each individual step is sound.

Most of what looks like a reasoning failure is actually a context failure of this kind. The model isn’t dumb; it’s been fed a lie and is dutifully building on it.

What I design against it:

  • Treat tool outputs as untrusted input. Validate before they enter the working context, the way you’d validate a form submission.
  • Distill, don’t dump. A 4,000-token raw payload carries maybe 40 tokens of signal and 3,960 tokens of opportunity to mislead. Summarize before it lands.
  • Re-fetch volatile state before irreversible actions instead of trusting a value from twelve steps ago.

4. Goal drift

On a long trajectory the agent slowly forgets what it was asked to do. By step fifteen it’s diligently solving a subproblem it invented at step nine, and the user’s original request has faded out of attention. No single step is wrong. The cumulative wander is.

Drift is an attention-geography problem. The original goal sits far up a long transcript, the recent steps are fresh and loud, and the model’s focus follows recency. Presence in the context isn’t the same as salience.

What I design against it:

  • Restate the goal near the end of the prompt, where it’s freshest, not just once at the top where it decays.
  • Compress history into a running summary that keeps the goal and open constraints explicit instead of letting them bury.
  • Checkpoint against the goal between steps: does the remaining plan still serve the original ask?

5. Wrong-tool / tool-misuse

The agent picks the wrong tool, or the right tool with wrong arguments. It calls delete when it meant archive, or passes a field that doesn’t exist, or chooses between two overlapping tools and picks badly.

This one is almost always self-inflicted at design time. Too many tools, overlapping tools, vague descriptions, loose argument types. The model is guessing from a paragraph of description, and a sloppy interface gives it room to guess wrong. The fix lives in the tool definitions, not the model.

What I design against it:

  • Fewer, sharper tools. Every tool added makes every other tool harder to pick correctly.
  • Closed enums over free strings. A status the model can’t typo into existence is a failure it can’t have.
  • Error messages that name the recovery move, so a wrong call becomes a corrected call instead of a dead end.
  • Gate the irreversible ones. Delete, send, charge — those get a confirmation or a dry-run, never a raw call.

6. Coordination failure

This one only shows up in multi-agent systems, and it shows up reliably. Information gets dropped, duplicated, or corrupted across an agent boundary. The orchestrator compresses what it knows into a handoff message; the worker acts on the compression and misses the nuance that got cut. Or two agents both write the same record and race.

Every boundary between agents is a lossy channel. The handoff can only carry what the sender thought to include, and whatever it omitted is simply gone from the receiver’s world.

What I design against it:

  • Don’t split tightly-coupled work in the first place. The best coordination failure is the boundary you never created.
  • Structured, validated, logged handoffs. When the system does something inexplicable, the boundary log is the first place I look, because the bug is almost always in a handoff and not inside an agent.
  • Gate irreversible actions at the orchestrator, never inside a worker, so no single specialist can act alone on a confident wrong judgment.

The map

Here’s the whole guide in one view, because the categories cluster cleanly once you can see them side by side:

FailureTellRoot causePrimary defense
Looprepeats near-identical actionsreactive loop, no anchorstep cap + plan + loop detection
Hallucinated progressreports success it didn’t earnnarrates plan, skips verificationverify against the world per step
Context poisoningflawless reasoning, wrong premisebad fact entered context earlyvalidate + distill tool outputs
Goal driftsolves the wrong subproblemgoal lost salience in long contextrestate goal late, compress history
Wrong-toolbad tool or bad argumentscluttered/vague tool surfacefewer sharp tools, enums, gating
Coordinationdropped/corrupted across boundarylossy handoff, shared statedon’t split; log + gate handoffs

What strikes me looking at this table is how few of the defenses are about the model. A step cap, verification against state, output validation, goal restatement, tool design, handoff discipline — these are all things I control in the architecture. The model is a constant. The failure modes are mostly things I either designed against or designed into the system.

What this changes about how I build

Once the failures stopped looking random, my whole posture changed. I no longer wait for an agent to surprise me and then patch the symptom. I build the defenses in from the start, because I already know which six shapes are coming. This is the chassis underneath Vontra, the AI-native business operating system I’m building — every agent that touches money or records runs inside these guardrails by default, not as an afterthought bolted on after the first bad night.

The pattern underneath all of them is the same one I keep returning to: autonomy is a cost, not a feature. Every step an agent takes freely is a step where one of these six can strike. So the engineering job isn’t to maximize autonomy. It’s to spend autonomy deliberately — give the agent freedom where the work is genuinely exploratory, and clamp it down with caps, verification, validation, and gates everywhere the cost of a failure is real.

before every irreversible action:
  re-read actual state          # guards poisoning + hallucinated progress
  confirm it still serves goal   # guards drift
  require explicit confirmation   # guards wrong-tool + coordination
throughout the loop:
  hard step cap                  # guards looping
  detect + break repetition       # guards looping

That little skeleton sits, in some form, inside every production agent I run. Not because I’m cautious by temperament, but because I’ve now met all six of these failures in the wild, more than once, and I’d rather design against a category than debug another incident at two in the morning. The demos never show you these. Production shows you nothing but. Build for the failures you know are coming, and the surprises get a lot rarer.

AGENTSFAILURE-MODESRELIABILITYPRODUCTIONDEBUGGING