The Graph Looks Right. The Merge Is Where It Breaks.
A multi-agent graph can lose a verdict with no error and nothing turning red. The bug is one line in the state schema.
- Claims
- 19
- Verified at the primary source
- 4
- Removed before publication
- 0
- Last checked
19 claims: 4 verified, 14 executed, 1 reported.
Download this ledger: CSV · JSON · Markdown · CC BY 4.0 · Query it from Claude or ChatGPT
The claim ladder
| Rung | Claim | Evidence | Whose behaviour it measures | Scope limit |
|---|---|---|---|---|
| 1 | The single-vs-multi-agent debate resolves to one rule: parallelise reads, keep writes single-threaded | Cognition vs Anthropic, reconciled by LangChain | Framework designers and practitioners, at the architecture level | A design heuristic, stated abstractly; it does not tell you where in your code the rule binds |
| 2 | In LangGraph that rule is a property of the state schema: a channel written by more than one parallel node is where writes collide | verify.py EXP 1, real InvalidUpdateError: At key 'decision': Can receive only one value per step (langgraph 0.6.11) | The LangGraph runtime | LangGraph specifically; other frameworks (handoffs, shared crew state) locate the same collision elsewhere |
| 3 | The framework refuses the blunt collision LOUDLY, and its own error routes you to the fix that makes it SILENT | The error says "Use an Annotated key"; add operator.add; the channel becomes ['ship it','hold','roll back'] and a consumer acting on decision[0] ignores two, no error | The builder's reaction to the error message | The silent failure needs a parallel CONSUMER of a decision channel; a single writer reading a findings list is safe by construction |
| 4 | So build it safe and audit any graph by its schema: parallel branches to isolated/append channels, one writer per decision channel, plus a recursion cap and a human gate | agent_graph_demo.py: safe run reconciles 3 of 3 with a human veto; cycle hits GraphRecursionError at 25; interrupt() needs a checkpointer | The reader's own graph | A discrimination the reader applies, not a benchmark; makes no claim about how often this fails in production |
What would make it wrong
The central claim fails if: (a) the InvalidUpdateError / silent-merge behaviour does not reproduce on current LangGraph at the stated version (it is version-pinned and reproduced by verify.py; a future version that raises on the reducer merge too would narrow the claim); or (b) the schema audit does not separate safe from unsafe graphs — a graph that passes the channel check still ships conflicting decisions, or one that fails it is actually fine. Either collapses the instrument.
Re-checked 24 Oct 20261 fired1 holdingThe re-check
Fired as worded
Condition (b) was already met on the day the piece went out.
The piece's first check reads the State schema, and the piece says that a plain decision channel two nodes write in sequence overwrites silently and "the schema cannot see it". So a graph can pass the schema audit and still ship conflicting decisions, which is what (b) says would show the claim wrong. The piece's second check, a runtime test that every write to a decision channel comes from one node, catches that case (the tool pack has shipped it as check_owners.py since 7 October), and the two checks together sort every decision graph in the tool pack correctly. Condition (a) still holds on LangGraph 1.2.17, so the reducer finding the piece is built on stands. The falsifier above stays as it was published, and the re-check is in the track record.
The evidence, row by row
Each row is a claim the essay makes, then the evidence recorded for it and the source it was checked against. For verified rows that is usually the exact words, where they sit and the day they were read. The label says how far it was checked.
What the labels mean
- Verified
- Checked against the primary source itself by a checker who did not draft the piece, usually with the exact words, where they sit and the date read.
- Executed
- A run or observation done for the piece: code, a query, a count, or a check made live in an app. The claim is what it returned. Run records are not published.
- Checked
- Checked against its source by a separate checker in the older ledger format, which recorded no quote, locator or date.
- Reported
- Not verified word for word against a primary source: carried from a secondary source, from one that could not be opened in full, or supported only in part. The essay words it accordingly.
- Struck
- Drafted, checked and removed before publication. Kept here, crossed out, with the reason.
- Excluded
- Considered and deliberately left out of the piece. Kept here with the reason.
Sources (5)
- First-party runs 14 rows
- Cognition 2 rows
- Anthropic engineering blog 1 row
- Cemri et al. 1 row
- Ranjan Kumar 1 row
-
Two parallel nodes writing one plain (LastValue) channel do not silently overwrite; LangGraph refuses and raises
Result: At key 'decision': Can receive only one value per step. Use an Annotated key to handle multiple values.
first-party own run, langgraph 0.6.11
A run or observation done for this piece. The run record is not published.
LinkReport an errorCite
A run or observation by The Durability Curve (first-party own run, langgraph 0.6.11). Checked in: Claim Ledger, "The Graph Looks Right. The Merge Is Where It Breaks.", The Durability Curve, row 1, https://durabilitycurve.com/claims/where-agents-disagree/#c-1 (source read 2026-08-29). -
Silencing that error with a last-write-wins reducer on the decision channel keeps one write and silently drops the rest, with no error
Result: the channel now holds: 'roll back' and silently dropped: ['ship it', 'hold'] (no error was raised)
first-party own run, langgraph 0.6.11
A run or observation done for this piece. The run record is not published.
LinkReport an errorCite
A run or observation by The Durability Curve (first-party own run, langgraph 0.6.11). Checked in: Claim Ledger, "The Graph Looks Right. The Merge Is Where It Breaks.", The Durability Curve, row 2, https://durabilitycurve.com/claims/where-agents-disagree/#c-2 (source read 2026-08-29). -
Which write survives follows node-name order (the node whose name sorts last in Python's default codepoint order wins, not case-insensitive alphabetical) and is stable across re-runs of the same graph; an undocumented implementation detail
Result: zebra=ship, alpha=hold, mike=roll -> survives: ship and determinism (same order x3): ['roll back', 'roll back', 'roll back']; codepoint check Zebra vs alpha -> alpha survives (Z=0x5A < a=0x61)
first-party own run, langgraph 0.6.11
A run or observation done for this piece. The run record is not published.
LinkReport an errorCite
A run or observation by The Durability Curve (first-party own run, langgraph 0.6.11). Checked in: Claim Ledger, "The Graph Looks Right. The Merge Is Where It Breaks.", The Durability Curve, row 3, https://durabilitycurve.com/claims/where-agents-disagree/#c-3 (source read 2026-08-29). -
The documented reducer operator.add is lossless: on a str channel it concatenates the writes in node-name (alphabetical) fold order; on a list channel it keeps all of them
Result: decision -> 'roll backship ithold' (str, release-gate fan-out changelog/metrics/tests, stable x3) and ['ship it', 'hold', 'roll back'] (list)
first-party own run, langgraph 0.6.11
A run or observation done for this piece. The run record is not published.
LinkReport an errorCite
A run or observation by The Durability Curve (first-party own run, langgraph 0.6.11). Checked in: Claim Ledger, "The Graph Looks Right. The Merge Is Where It Breaks.", The Durability Curve, row 4, https://durabilitycurve.com/claims/where-agents-disagree/#c-4 (source read 2026-08-29). -
The SAME reducer knob is correct on a gather channel: three read-workers append an isolated operator.add findings channel and a single writer reconciles all three
Result: findings reaching the single writer = 3 of 3 and reconciled 3 of 3
first-party own run, langgraph 0.6.11
A run or observation done for this piece. The run record is not published.
LinkReport an errorCite
A run or observation by The Durability Curve (first-party own run, langgraph 0.6.11). Checked in: Claim Ledger, "The Graph Looks Right. The Merge Is Where It Breaks.", The Durability Curve, row 5, https://durabilitycurve.com/claims/where-agents-disagree/#c-5 (source read 2026-08-29). -
A Send fan-out into a shared plain decision channel raises the same InvalidUpdateError
Result: raised InvalidUpdateError: At key 'decision': Can receive only one value per step.
first-party own run, langgraph 0.6.11
A run or observation done for this piece. The run record is not published.
LinkReport an errorCite
A run or observation by The Durability Curve (first-party own run, langgraph 0.6.11). Checked in: Claim Ledger, "The Graph Looks Right. The Merge Is Where It Breaks.", The Durability Curve, row 6, https://durabilitycurve.com/claims/where-agents-disagree/#c-6 (source read 2026-08-29). -
A cyclic graph with no stop condition halts at LangGraph's default recursion limit of 25 and raises GraphRecursionError
Result: Recursion limit of 25 reached without hitting a stop condition.
first-party own run, langgraph 0.6.11
A run or observation done for this piece. The run record is not published.
LinkReport an errorCite
A run or observation by The Durability Curve (first-party own run, langgraph 0.6.11). Checked in: Claim Ledger, "The Graph Looks Right. The Merge Is Where It Breaks.", The Durability Curve, row 7, https://durabilitycurve.com/claims/where-agents-disagree/#c-7 (source read 2026-08-29). -
interrupt() surfaces its payload with or without a checkpointer, but resuming needs one: without a checkpointer Command(resume=...) raises
Result: RuntimeError: Cannot use Command(resume=...) without checkpointer and (no-checkpointer first run) has __interrupt__: True
first-party own run, langgraph 0.6.11
A run or observation done for this piece. The run record is not published.
LinkReport an errorCite
A run or observation by The Durability Curve (first-party own run, langgraph 0.6.11). Checked in: Claim Ledger, "The Graph Looks Right. The Merge Is Where It Breaks.", The Durability Curve, row 8, https://durabilitycurve.com/claims/where-agents-disagree/#c-8 (source read 2026-08-29). -
On resume the interrupt node re-runs from the top, so a side effect above the interrupt() call happens twice
Result: side effect ran 2 times -> twice, claim SUPPORTED
first-party own run, langgraph 0.6.11
A run or observation done for this piece. The run record is not published.
LinkReport an errorCite
A run or observation by The Durability Curve (first-party own run, langgraph 0.6.11). Checked in: Claim Ledger, "The Graph Looks Right. The Merge Is Where It Breaks.", The Durability Curve, row 9, https://durabilitycurve.com/claims/where-agents-disagree/#c-9 (source read 2026-08-29). -
A plain channel written by two nodes in sequence (across supersteps) overwrites silently, no error; the first write is lost
Result: no error. final decision = 'B said ship' -> A's write silently lost
first-party own run, langgraph 0.6.11
A run or observation done for this piece. The run record is not published.
LinkReport an errorCite
A run or observation by The Durability Curve (first-party own run, langgraph 0.6.11). Checked in: Claim Ledger, "The Graph Looks Right. The Merge Is Where It Breaks.", The Durability Curve, row 10, https://durabilitycurve.com/claims/where-agents-disagree/#c-10 (source read 2026-08-29). -
LangGraph exposes no static per-node write set: a node's introspectable .channels is its read set (a node that writes only decision still lists the whole readable state)
Result: a.channels: ['decision', 'other']
first-party own run, langgraph 0.6.11
A run or observation done for this piece. The run record is not published.
LinkReport an errorCite
A run or observation by The Durability Curve (first-party own run, langgraph 0.6.11). Checked in: Claim Ledger, "The Graph Looks Right. The Merge Is Where It Breaks.", The Durability Curve, row 11, https://durabilitycurve.com/claims/where-agents-disagree/#c-11 (source read 2026-08-29). -
The safe demo makes exactly three worker model calls, one per read-worker
Result: model calls made: 3
first-party own run
A run or observation done for this piece. The run record is not published.
LinkReport an errorCite
A run or observation by The Durability Curve (first-party own run). Checked in: Claim Ledger, "The Graph Looks Right. The Merge Is Where It Breaks.", The Durability Curve, row 12, https://durabilitycurve.com/claims/where-agents-disagree/#c-12 (source read 2026-08-29). -
audit.py reads a State TypedDict and flags reducer channels (the fan-out silent-merge surface): findings on the safe schema, decision on the trap schema
Result: ! classify findings REDUCER (add) and fan-out safe decision plain
first-party own run (re-run 2026-08-29 after output cleanup)
A run or observation done for this piece. The run record is not published.
LinkReport an errorCite
A run or observation by The Durability Curve (first-party own run (re-run 2026-08-29 after output cleanup)). Checked in: Claim Ledger, "The Graph Looks Right. The Merge Is Where It Breaks.", The Durability Curve, row 13, https://durabilitycurve.com/claims/where-agents-disagree/#c-13 (source read 2026-08-29). -
Environment of record for every mechanism row
Result: langgraph 0.6.11 and langchain-core 0.3.86 and python 3.9.6
first-party own run
A run or observation done for this piece. The run record is not published.
LinkReport an errorCite
A run or observation by The Durability Curve (first-party own run). Checked in: Claim Ledger, "The Graph Looks Right. The Merge Is Where It Breaks.", The Durability Curve, row 14, https://durabilitycurve.com/claims/where-agents-disagree/#c-14 (source read 2026-08-29). -
Cognition argues actions carry implicit decisions and recommends a single-threaded linear agent
"Actions carry implicit decisions, and conflicting decisions carry bad results" · "The simplest way to follow the principles is to just use a single-threaded linear agent"
Cognition (Walden Yan), Don't Build Multi-Agents, 2025 · Principle 2; "A Theory of Building Long-running Agents" · cognition.com
LinkReport an errorCite
Cognition (Walden Yan), Don't Build Multi-Agents, 2025, Principle 2; "A Theory of Building Long-running Agents", https://cognition.com/blog/dont-build-multi-agents. Checked in: Claim Ledger, "The Graph Looks Right. The Merge Is Where It Breaks.", The Durability Curve, row 15, https://durabilitycurve.com/claims/where-agents-disagree/#c-15 (source read 2026-09-27). -
Cognition's 2026 follow-up concludes multi-agent systems work best when writes stay single-threaded and the extra agents add intelligence rather than actions (cited in [^2])
"multi-agent systems work best today when writes stay single-threaded and the additional agents contribute intelligence rather than actions"
Cognition (Walden Yan), Multi-Agents: What's Actually Working, 22 Apr 2026 · essay body (re-fetched at primary, 2026-08-29) · cognition.com
LinkReport an errorCite
Cognition (Walden Yan), Multi-Agents: What's Actually Working, 22 Apr 2026, essay body (re-fetched at primary, 2026-08-29), https://cognition.com/blog/multi-agents-working. Checked in: Claim Ledger, "The Graph Looks Right. The Merge Is Where It Breaks.", The Durability Curve, row 16, https://durabilitycurve.com/claims/where-agents-disagree/#c-16 (source read 2026-09-27). -
Anthropic reports its multi-agent research system uses about 15x the tokens of a chat
"multi-agent systems use about 15× more tokens than chats"
Anthropic engineering blog · "Benefits of a multi-agent system" · anthropic.com
LinkReport an errorCite
Anthropic engineering blog, "Benefits of a multi-agent system", https://www.anthropic.com/engineering/multi-agent-research-system. Checked in: Claim Ledger, "The Graph Looks Right. The Merge Is Where It Breaks.", The Durability Curve, row 17, https://durabilitycurve.com/claims/where-agents-disagree/#c-17 (source read 2026-09-27). -
The MAST study finds specification and system design the largest of three roughly balanced failure categories, and the authors trace many failures to system design rather than model limits alone
"The distribution of failures across MAST’s categories is relatively balanced (FC1: 41.77%, FC2: 36.94%, FC3: 21.30%, Figure 2)" · "many MAS failures came from system design, not just limitations of the underlying LLMs"
Cemri et al., "Why Do Multi-Agent LLM Systems Fail?", arXiv 2503.13657v2 · v2, "Balanced Distribution"; §5.2 "Beyond Model Capabilities: The Primacy of System Design" · arxiv.org
LinkReport an errorCite
Cemri et al., "Why Do Multi-Agent LLM Systems Fail?", arXiv 2503.13657v2, v2, "Balanced Distribution"; §5.2 "Beyond Model Capabilities: The Primacy of System Design", https://arxiv.org/abs/2503.13657v2. Checked in: Claim Ledger, "The Graph Looks Right. The Merge Is Where It Breaks.", The Durability Curve, row 18, https://durabilitycurve.com/claims/where-agents-disagree/#c-18 (source read 2026-09-27). -
Ranjan Kumar published the reducer-as-concurrency-policy framing and a compiled-graph merge-policy auditor before this piece (convergent prior art, credited in the body)
"The reducer is not a merge helper. It is the concurrency-control policy for that state key." · "It appears on no diagram, in no edge list, and in no type checker’s output."
Ranjan Kumar, "LangGraph Reducers Are a Concurrency Policy", 27 Jul 2026 · post body (re-fetched at primary, 2026-08-29) · ranjankumar.in
LinkReport an errorCite
Ranjan Kumar, "LangGraph Reducers Are a Concurrency Policy", 27 Jul 2026, post body (re-fetched at primary, 2026-08-29), https://ranjankumar.in/langgraph-reducers-concurrent-state-writes. Checked in: Claim Ledger, "The Graph Looks Right. The Merge Is Where It Breaks.", The Durability Curve, row 19, https://durabilitycurve.com/claims/where-agents-disagree/#c-19 (source read 2026-09-27).
No rows match. Clear the search or pick another label.
Cite and reuse
- A single claim
- Use the row's Cite button. It names the original source first, then this row, which carries its own link.
- This ledger
Floyd, Harry (2026). Claim Ledger: The Graph Looks Right. The Merge Is Where It Breaks. The Durability Curve. https://durabilitycurve.com/claims/where-agents-disagree/- The essay
Floyd, Harry (2026). The Graph Looks Right. The Merge Is Where It Breaks. The Durability Curve. https://durabilitycurve.com/blog/where-agents-disagree/
The ledger data is licensed CC BY 4.0: reuse it, quote it or train on it, with credit to The Durability Curve and a link. Read the licence. Machine copies: JSON, CSV, Markdown.
The newsletter · Free
Subscribe to get each new piece in your inbox, with something to use in every one.
Several essays a week, plus Notes through the week.
Signup completes on Substack. Unsubscribe from any email.