Two Agents, Zero Reasoning Errors, One Broken Merge — The Multi-Agent Bug Hiding in Plain Sight
Why this matters
Split the ticket. Spin up two agents. Merge the diffs. That's the default multi-agent playbook right now — and it works, right up until the moment it doesn't, in a way that makes you suspect the model before you suspect your own design. Most teams hit the same wall, and it's never because either agent reasoned badly. It's because the split was drawn in the wrong place.
Two correct fixes, one broken file
Here's what the failure actually looks like. An orchestrator fires off two subagents on the same feature: Agent A owns the frontend form, Agent B owns the backend API behind it. Both finish clean. Both diffs pass review — separately. Merge them and the feature breaks: one agent treats a field as required, the other treats it as optional, because a schema change one agent discovered mid-task never made it to the other.
Here's the move that actually matters in the postmortem: pull the model logs for both agents and read the reasoning traces, not just the diffs. Neither agent screwed up. Agent B looked at the migration file it was editing and correctly concluded the field should now allow null. Agent A correctly implemented required-field validation — because that was true when its context got assembled, and nothing in that context ever updated. Two agents, two locally correct chains of reasoning, one globally broken system. That's the signature of a context-partitioning failure, not a reasoning failure — check for that signature before you blame the model.
The actual bug: task labels aren't information boundaries
The orchestrator split the work by task type — frontend vs. backend. On paper that's a completely reasonable decomposition: it matches how a human team would divide the ticket, it matches the folder structure, it's basically how you'd write the Jira subtasks. And it has nothing to do with where the knowledge in this task actually forks.
A task boundary is about who does the work. An information boundary is about where a fact, once learned, stops mattering to everyone and starts mattering to only some. Those two lines overlap often enough that it's easy to assume they're the same thing — until a task straddles a shared contract (a schema, a config value, an API shape, a naming convention) that both halves depend on. Split by task label when that happens, and you silently split the fact in half too: each agent gets a snapshot of the world as it looked at dispatch time, and nothing ever tells either snapshot that the other one moved.
The diagnostic question
Before you hand a task label to any agent in a multi-agent run, ask one question: if this agent learns something mid-task, does the other agent need to know? If the answer is yes for even one thing either agent might discover, you don't have two independent tasks — you have one task with a fork point buried inside it, and that fork point needs an explicit handoff.
Run that question backward on the incident: would Agent A (frontend) need to know if Agent B (backend) changed the nullability of a field on the shared form? Obviously. Ask that one question at design time and you flag the schema as a fork point before either agent touches a line of code. No incident, no postmortem, no contradictory diffs to untangle.
- ▹List out every fact each agent might discover or decide mid-task — not just the ones you're expecting.
- ▹For each one, ask whether the other agent's correctness depends on it.
- ▹If yes: that fact needs a named owner and a place to live before either agent moves past it. It can't just sit in one agent's context window.
- ▹If no agent's work depends on what another agent finds, the task-label split is fine as-is.
The fix: re-split around the fork, not the task type
Before: two agents dispatched in parallel off the same starting prompt, each free to make schema-adjacent decisions on its own, merged at the end with zero synchronization in between.
BEFORE (task-label split)
Orchestrator
├── Agent A: "implement the frontend form for feature X"
└── Agent B: "implement the backend API for feature X"
(both run in parallel, no shared state, merge at the end)
AFTER (information-fork split)
Orchestrator
└── Agent B: "define the schema contract for feature X"
→ writes schema-contract.md (field names, types, nullability, validation rules)
Agent A: "implement the frontend form against schema-contract.md"
(blocked on B's artifact; consumes it, does not re-derive it)
Nothing about the agents changed. What changed is that the schema — the one fact both agents' correctness hinges on — got a single owner and a single written artifact. The second agent was made to consume that artifact instead of quietly re-deriving its own version of the same fact from a stale snapshot of the ticket.
The rule for Day 13
Orchestration design doesn't start with 'how many agents do I need' or 'how do I divide this ticket by role.' It starts with drawing the information-fork map: where in this task does a fact get discovered or decided that changes what someone else needs to know? Task labels and agent assignments get laid on top of that map — never the other way around. Assign agents to forks, not forks to agents. Get that backward and you'll get contradictions that read, in the logs, exactly like good reasoning.
Where this goes next
Look at what actually fixed the incident: not a smarter orchestrator, not better prompts, not a bigger model. A written artifact sitting at the fork point, handing both agents the same fact at the same time. That artifact — not either agent — is what made the system correct. That's where the next lesson picks up: the handoff artifact is the real unit of orchestration, and agents are just the workers reading and writing it.
Extend your knowledge
- ▹Take your last multi-agent task split and run the diagnostic question against every pair of agents: would one need to know what the other discovers? Any yes you find is an unhandled fork.
- ▹Look at how LangGraph handles shared graph state versus scoped subgraph context, and how CrewAI's task 'context' parameter passes prior task outputs between agents — both are structural attempts to solve exactly this problem.
- ▹Next time you write an orchestrator prompt, draft the information-fork map as its own artifact before you write the task assignments, and see how often the two disagree.
- ▹Day 14 goes deeper on the handoff artifact itself — what makes one durable enough that every agent reading it can actually trust it.
Discussion
Chat with Chi Cong (AI) about this article. Your conversation is private to you — you can publish a summary for others when you're done.