Skip to content

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

RungClaimEvidenceWhose behaviour it measuresScope limit
1The single-vs-multi-agent debate resolves to one rule: parallelise reads, keep writes single-threadedCognition vs Anthropic, reconciled by LangChainFramework designers and practitioners, at the architecture levelA design heuristic, stated abstractly; it does not tell you where in your code the rule binds
2In LangGraph that rule is a property of the state schema: a channel written by more than one parallel node is where writes collideverify.py EXP 1, real InvalidUpdateError: At key 'decision': Can receive only one value per step (langgraph 0.6.11)The LangGraph runtimeLangGraph specifically; other frameworks (handoffs, shared crew state) locate the same collision elsewhere
3The framework refuses the blunt collision LOUDLY, and its own error routes you to the fix that makes it SILENTThe 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 errorThe builder's reaction to the error messageThe silent failure needs a parallel CONSUMER of a decision channel; a single writer reading a findings list is safe by construction
4So 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 gateagent_graph_demo.py: safe run reconciles 3 of 3 with a human veto; cycle hits GraphRecursionError at 25; interrupt() needs a checkpointerThe reader's own graphA 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)
  1. First-party runs 14 rows
  2. Cognition 2 rows
  3. Anthropic engineering blog 1 row
  4. Cemri et al. 1 row
  5. Ranjan Kumar 1 row
  1. 1 Executed Read

    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.

    Link
    Cite

    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).

    Report an error
  2. 2 Executed Read

    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.

    Link
    Cite

    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).

    Report an error
  3. 3 Executed Read

    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.

    Link
    Cite

    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).

    Report an error
  4. 4 Executed Read

    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.

    Link
    Cite

    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).

    Report an error
  5. 5 Executed Read

    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.

    Link
    Cite

    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).

    Report an error
  6. 6 Executed Read

    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.

    Link
    Cite

    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).

    Report an error
  7. 7 Executed Read

    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.

    Link
    Cite

    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).

    Report an error
  8. 8 Executed Read

    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.

    Link
    Cite

    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).

    Report an error
  9. 9 Executed Read

    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.

    Link
    Cite

    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).

    Report an error
  10. 10 Executed Read

    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.

    Link
    Cite

    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).

    Report an error
  11. 11 Executed Read

    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.

    Link
    Cite

    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).

    Report an error
  12. 12 Executed Read

    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.

    Link
    Cite

    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).

    Report an error
  13. 13 Executed Read

    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.

    Link
    Cite

    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).

    Report an error
  14. 14 Executed Read

    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.

    Link
    Cite

    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).

    Report an error
  15. 15 Verified Read

    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

    Link
    Cite

    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).

    Report an error
  16. 16 Verified Read

    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

    Link
    Cite

    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).

    Report an error
  17. 17 Verified Read

    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

    Link
    Cite

    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).

    Report an error
  18. 18 Reported Read

    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

    Link
    Cite

    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).

    Report an error
  19. 19 Verified Read

    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

    Link
    Cite

    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).

    Report an error

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.