VIVUU

Field notes · running agents

AI agent failure modes: what actually goes wrong

Notes from running coding agents against real repositories behind an approval gate. Only one of the six failures below is the kind people expect from a language model — the rest are systems failures that happen to involve one.

1. The plan is confident and wrong

Asked to fix a content-security policy, an agent proposed replacing the live authentication domain with a stale one belonging to an unrelated project — and wrote a fluent rationale explaining why the stale domain was correct. Applied, it would have broken sign-in.

The summary was excellent. This is the failure that makes summaries dangerous: fluency is what a language model is best at, and it is uncorrelated with whether the diff is right. It was caught because the gate showed the diff. Full write-up here.

2. Success with nothing to show for it

A run completed. Status: success. Applied edits: zero. The plan had claimed changes, every edit failed to match its anchor text, and nothing threw an exception — so the pipeline reported completion and parked a confident summary at the approval gate with an empty patch attached.

run 1732c641 · status success · applied 0 · diff empty ← not a success
run 80f2f726 · status parked · applied 1 · +4 lines ← real work

Twice, a human was asked to approve a no-op described as an improvement. The fix is a rule, not a model change: if the plan claimed edits and none applied, the run failed — and the per-edit reason is the output worth having.

3. Vocabulary drift into default-deny

A benign plan was refused because the model asked for repo.pull_request while the policy knew pr.create. Default-deny worked exactly as designed and blocked useful work, because the action vocabulary is generated text like everything else the model produces.

The fix is canonicalising synonyms before matching and pinning the exact vocabulary in the planning prompt. The wrong fix is relaxing default-deny, which trades a visible annoyance for an invisible risk. It shows up as repeated denials on the same action — which is why clustering denials is worth more than counting them.

4. The workspace is gone

A task planned, worked, and parked at the gate. Approved an hour later, delivery failed: the isolated workspace no longer existed, because resumption ran inside a process that had since restarted.

Any gated pipeline has this shape — a pause of arbitrary length between work and delivery — so the work must outlive the process that produced it. Archiving the patch as an artifact and rebuilding the container from artifact plus source makes approval-hours-later safe. We tested it by deliberately redeploying the worker while a task sat parked; the approval still produced a pull request.

5. Silent truncation: it only saw part of the file

An agent was asked to edit an entry in a 1.4 MB JSON file. It refused, honestly, saying it could not craft an exact replacement without seeing the target. The reason was a read limit: the file was fed to the model head-first up to a cap, and the entry sat past it.

Worse was the near-miss underneath. The same capped read was being used to apply edits, so a match inside the visible portion would have written the truncated head back as the whole file — deleting the remainder in the branch. The agent’s refusal was the correct behaviour and it masked a data-loss bug in the harness.

6. Honest refusal, which reads like failure

Related and worth separating: an agent that says “I cannot do this safely with what I can see” has succeeded at the thing that matters. Eight sourcing attempts in one project ended in refusals before one produced a real diff — and every refusal named a genuine reason: the entry was not visible, the field did not exist yet, no verbatim anchor could be quoted.

A pipeline that punishes refusal — by retrying until something applies — converts the safest failure mode into the most dangerous one. Read the refusals; they are usually describing a defect in what you gave the agent.

The pattern

Five of the six are not model failures. They are truncation limits, process lifetimes, vocabulary mismatches and success semantics — plain systems engineering, in a system whose most visible component happens to be a language model.

Which suggests where the effort goes: not into better prompting, but into making the harness honest. Verify rather than believe the reported status, keep work reconstructible across restarts, canonicalise before you match, and never let a paraphrase stand in for the diff.

FAQ

What are the most common AI agent failure modes?
In practice, six: a plan that is confidently wrong, a run that reports success while producing nothing, action-name drift that trips a default-deny policy, a lost execution workspace, silent truncation where the agent only saw part of a file, and honest refusal when it cannot see enough to act. Only the first looks like the failure people expect from language models — the rest are systems failures wearing an agent's clothes.
Why do AI agents fail in production more than in demos?
Demos run on small, clean repositories where every relevant file fits in the context window and every action name matches the example. Production has a 1.4 MB content file where the target entry sits past the read limit, a policy vocabulary the model has never seen, and a worker that gets redeployed mid-task. None of those are model quality problems, and none of them appear in a demo.
Do agents report success when they have failed?
Yes, and it is the failure mode most worth engineering against. A run can finish, report success, and have applied zero edits — the plan claimed changes, every edit failed to match, and the pipeline reported completion because nothing threw. Treat a claimed success with an empty diff as a failure and surface the per-edit reasons, or you will ship nothing and believe you shipped something.
What is action-name drift?
The model asks for a capability using a name your policy does not recognise — 'repo.pull_request' where the rules say 'pr.create' — and a default-deny policy correctly refuses a perfectly benign plan. The fix is canonicalising synonyms and pinning the vocabulary in the planning prompt, not loosening the default. It shows up as a cluster of denials on the same action, which is why denial clustering is worth monitoring.
How do you make agent failures survivable?
Assume every stage can die and make the work reconstructible. Archive the patch as an artifact rather than holding it in a live workspace, so an approval hours later can rebuild the container from the artifact plus the source. We proved this by deliberately redeploying the worker while a task sat parked at the gate — the approval still delivered a pull request.

see the whole flow, live

Everything on this page — the queue, the evidence, the hold-to-approve, the audit trail — is working in the VIVUU terminal as an interactive preview on realistic mock data. No sign-up.