| name | agentic-failure-modes |
| description | MASFT taxonomy of multi-agent failure modes (Berkeley 2025) — 14 modes in 3 categories. Five industry-recurring modes: hallucinated actions, scope creep, cascading errors, context loss, tool misuse. Detection, monitoring, and mitigation patterns. Sources: rohitg00/ai-engineering-from-scratch (Apache-2.0). |
/agentic-failure-modes
When to Use
- Post-mortem: agent produced wrong output and you need to classify the failure
- Pre-deployment: instrument a new agent to detect common failure patterns before they hit users
- Monitoring: wire failure-mode detectors into production traces
- Architecture review: ensure mitigations exist for each of the 5 recurring failure types
Do NOT use for
- LLM base model evaluation (failures here are system/orchestration level, not model-level)
- Prompt engineering improvements (separate from failure mode detection)
MASFT: the 14 failure modes (Berkeley, arXiv:2503.13657)
Category 1: Communication failures
1. Ambiguous instruction transmission
2. Information loss across agents (context not forwarded)
3. Conflicting instructions from multiple orchestrators
4. Trust boundary collapse (tool output treated as trusted instruction)
5. Protocol mismatch (agents expect different message formats)
Category 2: Reasoning failures
6. Hallucinated actions (tool call that doesn't exist / wrong arguments)
7. Long-range contextual misuse (forgetting early-turn constraint)
8. Sub-intention errors (omission, redundancy, disorder of plan steps)
9. Instruction-following deviation (ignores system prompt)
10. Success hallucination (declares done after 400 error)
Category 3: Coordination failures
11. Scope creep (expands task beyond user's ask)
12. Cascading errors (one wrong call triggers downstream multi-system incident)
13. Mission drift (agent's objective shifts over long execution)
14. Monoculture collapse (all agents in a debate reach same wrong answer)
The 5 industry-recurring modes and mitigations
from dataclasses import dataclass
from typing import Literal
FailureMode = Literal[
"hallucinated_action",
"scope_creep",
"cascading_error",
"context_loss",
"tool_misuse",
]
@dataclass
class FailureSignal:
mode: FailureMode
evidence: str
severity: Literal["critical", "warning", "info"]
def detect_failure_signals(trace: list[dict]) -> list[FailureSignal]:
"""Scan an agent trace for known failure signatures."""
signals = []
action_history: list[str] = []
for step in trace:
role = step.get("role", "")
content = step.get("content", "")
if role == "assistant" and "Action:" in content:
import re
m = re.search(r'Action:\s*(\w+)', content)
tool = m.group(1) if m else None
if tool and tool step.get(, []):
signals.append(FailureSignal(, , ))
role == ( content content.lower()):
next_step = trace[trace.index(step) + ] trace.index(step) + < (trace) {}
next_content = next_step.get(, )
(phrase next_content.lower() phrase [, , ]):
signals.append(FailureSignal(,
, ))
role == content.lower():
re
paths = re.findall(, content, re.IGNORECASE)
path paths:
(x path x [, , , ]):
signals.append(FailureSignal(,
, ))
role == content:
re
action_sig = re.search(, content)
action_sig:
sig = action_sig.group()
sig action_history:
signals.append(FailureSignal(,
, ))
action_history.append(sig)
signals
Cascading error: the killer failure mode
Anatomy of a cascade:
Step 1: Agent hallucinates a product SKU "PROD-9999"
Step 2: Inventory API returns 404 — agent ignores the error
Step 3: Order placed with invalid SKU
Step 4: Payment processed (charge real money)
Step 5: Fulfillment system crashes on bad SKU
Step 6: Support ticket auto-created
→ Multi-system incident from one hallucinated string
Root problem: agents cannot distinguish "I failed" from "task is impossible"
→ They hallucinate success on errors to close the loop.
Mitigation: require re-probing after every destructive or external call.
def verify_state_after_action(tool_name: str, args: dict, result: str, re_probe: callable) -> bool:
"""Re-probe state after any write/external action. Don't trust the return value."""
if tool_name in ("create_order", "send_email", "deploy", "write_file"):
actual_state = re_probe(**args)
if "error" in actual_state.lower() or "not found" in actual_state.lower():
raise RuntimeError(f"State re-probe failed after {tool_name}: {actual_state}")
return True
Monitoring: wire into OTel traces
from opentelemetry import trace
def emit_failure_events(span, signals: list[FailureSignal]) -> None:
for s in signals:
span.add_event(
name=f"agent.failure_mode.{s.mode}",
attributes={
"failure.mode": s.mode,
"failure.severity": s.severity,
"failure.evidence": s.evidence[:500],
}
)
critical = [s for s in signals if s.severity == "critical"]
if critical:
span.set_status(trace.StatusCode.ERROR, f"{len(critical)} critical failure(s)")
Anti-Fake-Pass Checklist
❌ No re-probe after destructive actions → cascades go undetected until downstream incident
❌ Tool errors not surfaced as observations → agent hallucinates success; error is silently swallowed
❌ No failure-mode monitoring → post-mortems rely on manual trace inspection
❌ Trust boundary collapse ignored → tool output appended raw → prompt injection
❌ "Task complete" accepted at face value → always check actual state, not agent's self-report
❌ Same model family for all agents in a debate → monoculture collapse; errors correlate