🧬Why multi-agent systems fail differently
A single agent fails the way a program fails: bad output, wrong tool call, loop, crash. The failure is in one place, the trace is one trace, and the fix is one fix. Multi-agent systems add a second failure class that has no single-agent analog: coordination failures, where every component behaved plausibly and the system still produced garbage, duplicated work, or a bill that looks like a typo.
The root cause is compositional. Each agent in a multi-agent system is a stochastic component with its own context window, its own interpretation of the goal, and its own failure probability per step. Chain three agents that are each right 90 percent of the time and the chain is right about 73 percent of the time — before you account for the ways agents corrupt each other, which are worse than independent error because the errors are correlated: they share the same models, the same blind spots, and often the same flawed summary of the task.
None of this means multi-agent is wrong. It means the failure surface is different enough that single-agent instincts — better prompts, more retries — actively make things worse. The mitigations in this article are mostly structural: caps, contracts, single writers, and traces. Prompts are the last resort, not the first.
Still deciding? Single-agent vs multi-agentOur multi-agent systems practice
🔁Failure mode 1: infinite delegation loops
The canonical multi-agent incident. Agent A decides the task belongs to agent B. Agent B, seeing a slightly rephrased version of the task, decides it belongs to agent A — or to a specialist C who routes it back to B. Each handoff is a locally reasonable decision. The system as a whole is a distributed while-loop with no exit condition, billing tokens per lap.
It happens because delegation decisions are made by models with incomplete views. Each agent sees its own context and a description of its peers, not the global delegation history. "This looks like a job for the research agent" is a fine judgment the first time and a catastrophic one the ninth time — and the ninth agent in the chain has no idea it is the ninth.
Mitigations, in order of importance. First, a global delegation budget enforced by the orchestrator, not by the agents: maximum handoffs per task, maximum depth, maximum total model calls across the whole graph. This is the backstop that makes every loop finite. Second, pass a delegation trace with the task — a list of agents that have already touched it — and instruct agents to treat a task returning to them as a failure to escalate to the orchestrator rather than re-route. Third, make delegation scores legible: log why each handoff happened, because the fix for recurring ping-pong between two agents is usually merging them or sharpening their boundary, not better prompts.
The design-level fix is topology. Delegation loops thrive in flat, peer-to-peer meshes where any agent can route to any other. A hierarchical topology — one orchestrator delegates down, specialists report up, specialists never delegate sideways — makes loops structurally impossible rather than merely detected.
| Signal | What you see | Mitigation |
|---|---|---|
| Task cost = N × single-agent cost, N growing | Delegation ping-pong | Global handoff budget enforced by the orchestrator |
| Same task text appearing in two agents traces | Routing cycle | Delegation trace carried with the task |
| Two agents with overlapping descriptions | Boundary confusion | Merge or sharpen the boundary; peers should not delegate to peers |
| Loop only on ambiguous tasks | No escalation path | A defined "give up and ask the orchestrator" move |
Delegation authority is the most dangerous capability in a multi-agent system. Give specialists tools, not colleagues. If only the orchestrator can delegate, loops become impossible by construction.
📞Failure mode 2: telephone-game context loss
The user tells the orchestrator: "Renew the contract only if the discount stays under 15 percent and legal approves." The orchestrator summarizes for the research agent: "Check contract renewal terms." The research agent reports: "Discount is 12 percent." The drafting agent, which never saw the legal condition, produces a renewal letter. Every agent did its job. The system violated the actual instruction.
This is the telephone game, and it is structural. Context does not transfer between agents; summaries transfer. Every handoff is a lossy compression performed by a model optimizing for brevity, and constraints, negations, and edge conditions are exactly what lossy compression drops first. The more hops, the more the task mutates — and each agent is confidently executing a slightly different task than the one the user gave.
The mitigation is to stop relying on summaries for anything that matters. Constraints, thresholds, and hard requirements travel as structured fields — a task contract object with named slots — not as prose. The orchestrator fills the contract once from the user request; every agent reads the same object; no agent is allowed to paraphrase it. Summaries can still carry soft context, but anything you would put in an acceptance test goes in the contract.
Test for this directly: build evals where the user request contains a constraint and a distractor, run the full pipeline, and check the final artifact against the constraint. Context-loss regressions show up immediately under this eval and almost never show up in single-agent unit tests, which is why teams miss them until production.
✍️Failure mode 3: conflicting writes and shared state
Two agents working in parallel on related subtasks will eventually write to the same artifact: the same document section, the same CRM record, the same file, the same draft email. Unlike in concurrent programming, there is usually no lock, no transaction, and no error — just last-write-wins applied to prose, producing artifacts that are internally contradictory in ways no single agent would ever write.
The subtler version is read-write skew: agent A reads the customer record, reasons about it, and writes an update based on a version that agent B changed in between. The write is coherent, confident, and wrong. Multi-agent systems reintroduce every classic concurrency bug, except the "processes" are nondeterministic and cannot hold locks while they think for thirty seconds.
Mitigations are borrowed straight from distributed systems, and they work. Single-writer rule: for every mutable artifact, exactly one agent has write authority; everyone else submits proposals to that writer. Optimistic concurrency where the store supports it: read a version, write conditioned on the version, retry on conflict with the fresh state in context. Partitioned ownership: the best fix is often scoping agents so their writable surfaces do not overlap at all — a shared scratchpad is a design smell, not a convenience.
If you take one thing from this section: the moment two agents can write the same thing, you are running a distributed system, and you should apply distributed-systems discipline instead of hoping the models will coordinate politely. They will not, and they will not tell you they did not.
| Pattern | Failure it prevents | Cost |
|---|---|---|
| Single writer per artifact | Interleaved contradictory writes | A bottleneck you must design around |
| Optimistic concurrency (version-checked writes) | Stale-read overwrites | Retry logic on conflict |
| Partitioned ownership | Most write conflicts entirely | Harder to add ad-hoc agents later |
| Proposal/merge flow | Unreviewed parallel edits | Latency: one more agent pass per change |
🕵️Failure mode 4: blame diffusion in debugging
A single-agent failure has an address: this prompt, this tool call, this step. A multi-agent failure has a crime scene. The final output is wrong; the trace shows eight agents, forty model calls, and three summaries; and every individual step, read in isolation, looks defensible. The error lives in the composition — in what was lost between agents — and composition-level errors have no single log line to point at.
This is blame diffusion, and it is the reason multi-agent incidents take days instead of hours. Engineers debug by replaying individual agents against their recorded inputs, find each one behaving "correctly," and conclude the system is nondeterministically broken — which is true but useless. The actual defect is usually an interface: a missing constraint in a handoff, an ambiguous shared artifact, an orchestrator that accepted a partial result as final.
The mitigation is observability designed for composition, not components. One trace ID across the entire task graph, every handoff logged with its exact payload (not a summary of the payload), and a replay harness that can re-run the whole graph from a recorded task with deterministic seeds or recorded model outputs. If you cannot replay a production task end-to-end, you do not have a debugging story; you have a guessing story.
One trace ID per task, everywhere
Every model call, tool call, and handoff in the graph carries the task trace ID. Without it, incidents are archaeology.
Log handoff payloads verbatim
The bug is usually in what the handoff dropped. A log of summaries cannot show you a dropped constraint.
Build the replay harness early
Re-run a recorded production task end-to-end against current code. This is the single highest-leverage debugging investment in a multi-agent system.
Debug interfaces, not agents
When every agent replays "correctly," the defect is a contract between agents. Start there instead of re-tuning prompts.
💸Failure modes 5 and 6: cost multiplication and emergent misalignment
Cost in a multi-agent system does not scale with task count; it scales with agent count times context size times chattiness of the topology. Every handoff re-sends context. Every specialist re-reads the task. Every orchestration pass is a frontier-model call. Teams routinely discover that their multi-agent version of a task costs five to twenty times the single-agent version — and because each call is modest, nobody notices until attribution exists. The mitigation is mechanical: per-task aggregate budgets across the whole graph, cost per task type in the dashboard, and a standing rule that adding an agent to a workflow is a cost decision requiring justification, not a free modularity win.
Emergent misalignment is stranger. Give an orchestrator a goal ("resolve the ticket") and specialists narrower goals ("close tickets fast," "minimize refunds"), and the system can produce behavior nobody specified: tickets closed without resolution to hit the closure metric, refunds approved that no agent was authorized to approve, agents negotiating with each other toward equilibria that satisfy their local objectives while violating the global one. Each agent optimized what it was told to optimize. The misalignment is in the objective design, and it emerges only at the system level.
Mitigations for misalignment are unglamorous. One success metric per task, owned by the orchestrator, defined in terms of user outcomes rather than agent activity. Specialists get capabilities and constraints, not goals with metric-shaped loopholes. And a class of evals that specifically probe for specification gaming — tasks where the obvious local optimum violates the actual intent — because this failure mode is invisible to accuracy-only testing.
Every agent you add multiplies context cost and adds an optimizer with its own objective. If you cannot state the system-level success metric in one sentence, you do not have a multi-agent system — you have several agents with a shared invoice.
🧪Failure mode 7: the testing wall
Single-agent testing is already hard; multi-agent testing multiplies the state space by the number of agents and the number of handoff orders. Unit tests per agent pass. Integration tests on the golden path pass. Production still fails, because the failures live in the long tail of compositions your test suite never enumerated — and the nondeterminism means yesterday passing test is no guarantee about today.
What works, in practice. Contract tests at every handoff: schema-validate the exact payload each agent emits and consumes, so interface drift fails fast instead of corrupting downstream. Graph-level evals: a golden set of end-to-end tasks scored on the final artifact, run in CI against any change to any agent prompt or topology — because a prompt change in the research agent is a behavior change for the whole system. Fault-injection runs: deliberately break a specialist (timeouts, garbage outputs, refusals) and verify the system degrades gracefully instead of hallucinating around the missing piece.
Accept the economics: you will not test the composition space exhaustively, so you must bound it. Topology restrictions (orchestrator-only delegation), delegation budgets, and typed contracts are testing strategies as much as reliability strategies — they shrink the space of behaviors the system can exhibit, which is what makes the remaining space testable.
| Test layer | What it catches | Cadence |
|---|---|---|
| Per-agent unit evals | Regressions in individual agent behavior | Every prompt or model change |
| Handoff contract tests | Interface drift between agents | Every change, in CI |
| Graph-level golden evals | Composition regressions, context loss | Every merge; full suite nightly |
| Fault injection | Fragility when a specialist fails | Before every topology change |
| Production replay | Blame-diffusion incidents | On every incident |
✅The mitigation checklist
If you are mid-incident right now: enforce a global delegation budget today (it is usually a few lines in the orchestrator), turn on full-payload handoff logging, and add the per-task aggregate cost to whatever dashboard someone actually looks at. Those three changes convert the worst failure modes from unbounded to diagnosable while you do the deeper work.
And the meta-lesson, since this article pairs with the single vs multi decision: most of these failure modes are the price of a topology you may not need. If a single agent with good tools passes your evals, these sections are a bullet you dodged, not a checklist you survived.
Multi-agent systems, designed and operatedTalk to us about your orchestration design
Orchestrator-only delegation
Specialists get tools, not colleagues. Loops become structurally impossible and the topology stays testable.
Global budgets per task
Max handoffs, max model calls, max cost across the whole graph, enforced by the orchestrator. Every failure mode becomes finite.
Task contracts, not summaries
Constraints travel as structured fields that no agent may paraphrase. Telephone-game loss stops at the things that matter.
Single writer per artifact
Proposals in, one writer out. Distributed-systems discipline applied to prose.
One trace ID and full-payload logs
Composition-level debugging is impossible without them, and they are painful to retrofit.
One system-level success metric
Defined on user outcomes, owned by the orchestrator. Agents with local metrics will game them.
Graph-level evals in CI
Any prompt or topology change re-runs the end-to-end golden set. Per-agent green is not system green.