What you’ll be able to do
- Return structured error context (failure type, what was attempted, partial results, alternatives) so the coordinator can choose a recovery
- Distinguish access failures from valid empty results in what a subagent reports
- Recover locally from transient failures and propagate only what the subagent cannot resolve
- Annotate synthesis output with coverage: which findings are well supported and which areas have gaps
What you need to know
The coordinator can only recover from what it can see
In a coordinator–subagent system, the coordinator decides what happens after a failure: retry with a different query, route to another subagent, continue with partial results, or tell the user something is missing. Each of those decisions needs information. If the subagent's report says only "search unavailable," the coordinator can't tell whether the source timed out, rejected the query, or returned partial data before failing, so it can't choose well.
A useful error report carries structured error context:
- Failure type: timeout, access/permission denied, malformed query, source error.
- What was attempted: the query, the source, the parameters.
- Partial results: anything retrieved before the failure.
- Potential alternatives: a narrower query, a different source, a later retry.
Access failure is not the same as “nothing found”
These two outcomes look similar (no results) and mean opposite things:
- Access failure: the query didn't complete because of a timeout, an unreachable source, or a permission error. We don't know whether matching data exists. This needs a retry decision.
- Valid empty result: the query ran successfully and nothing matched. That is a finding in its own right ("no recalls were filed for this product") and shouldn't be retried.
The subagent's report must make the distinction explicit. If both come back as an empty list, the coordinator will either retry real negatives pointlessly or, worse, report "no evidence found" for a source it never managed to read.
Two opposite anti-patterns
- Silent suppression. Catching the error and returning an empty result marked as success. The workflow keeps going, but the gap is invisible. The final report confidently omits whatever that source would have contributed, and nothing downstream knows to look.
- Whole-workflow termination. Letting one subagent's exception propagate to a top-level handler that aborts the run. Nine subagents' good work is discarded because the tenth timed out, when the coordinator could have retried, rerouted, or proceeded with a noted gap.
The right behavior sits between them: surface the failure, with context, to the component that can decide what to do about it.
Recover locally, propagate what you can’t resolve
Not every failure needs to reach the coordinator. A transient failure, like a brief timeout or a momentary source error, is best handled inside the subagent with a small number of local retries. Pushing every hiccup upward clutters the coordinator's context and turns it into a retry loop.
When local recovery doesn't work, the subagent propagates the error, and it includes what it attempted (including the retries it already made) and any partial results. That stops the coordinator from repeating the same retries and lets it use whatever was salvaged. Errors the subagent can't fix at all, such as a permission denial, should be propagated straight away rather than retried.
Make coverage visible in the final output
Error handling doesn't end at the coordinator. If a source stayed unavailable and the system continued with partial results, the synthesized report needs to say so. Structure the synthesis output with coverage annotations: which findings are well supported by multiple sources, and which topic areas have gaps because a source was unavailable.
A reader can then treat the conclusions according to how well each area was covered, instead of assuming everything was checked equally.
Key concept
Subagents retry transient failures locally and propagate only what they can’t resolve, as structured context: failure type, what was attempted, partial results, alternatives. Keep access failures distinct from valid empty results, never disguise a failure as success, never abort the whole run over one failure, and annotate coverage gaps in the final output.
When a scenario shows a report that silently omits an area, look for an error that was converted into an empty success. When a scenario shows a run that died over one timeout, look for propagation straight to a top-level handler.
Practice scenario
{"results": []} with a success status so that "one flaky source doesn't break the run."Work it through, then open this
The subagent is suppressing an access failure and presenting it as a valid empty result, so the coordinator and synthesis agent reasonably conclude there’s nothing to report about Latin America. The fix is not to abort the run on failure, which is the opposite anti-pattern. Have the subagent retry transient timeouts locally a few times, then propagate a structured error (failure type, attempted query, retries made, partial results, possible alternatives) clearly marked as an access failure. The coordinator can then reroute or proceed, and the synthesis output should carry a coverage annotation flagging Latin America as a gap rather than a negative finding.
Build exercise — Design an error contract for a subagent
Intermediate · 30 min
What you’ll learn
- Defining a structured error shape a coordinator can act on
- Separating access failures from valid empty results
- Carrying coverage gaps through to the final output
-
For one subagent in a multi-agent design, define the shape of its result for three outcomes: success with results, success with no matches, and failure. The failure shape should include failure type, what was attempted, partial results, and alternatives.
- Why: If the shape can’t express the difference between those outcomes, the coordinator can’t respond differently to them.
- You should see: Three distinct shapes, where “no matches” and “failed” can’t be confused.
-
Decide which failure types the subagent handles locally (e.g. transient timeouts, retried a small fixed number of times) and which it propagates immediately (e.g. permission denied). Record the retries in the propagated error.
- Why: Local recovery keeps the coordinator’s context for decisions only it can make, and reporting attempts avoids duplicate retries.
- You should see: A short rule table and an error example showing the local attempts already made.
-
Simulate one source failing permanently and check the final report.
- Why: The point of propagation is that the gap survives to the reader.
- You should see: A coverage section naming the affected topic area as a gap due to an unavailable source, while the rest of the report completes normally.
Exam traps
Returning a generic status such as “search unavailable” that hides what failed and what was tried
The coordinator can’t choose a recovery without the failure type, the attempted query, partial results, and alternatives.
Catching a failure and returning an empty result marked as success
This hides the gap, so downstream agents report missing coverage as a negative finding.
Terminating the entire workflow because one subagent failed
Discards everything else that succeeded. Propagate the error to the coordinator so it can retry, reroute, or proceed with a noted gap.
Treating a timeout and a query with zero matches as the same outcome
A timeout needs a retry decision; a valid empty result is a finding. The report must keep them distinct.
Propagating every transient failure to the coordinator instead of retrying locally first
Transient failures are best retried inside the subagent. Propagate only what local recovery can’t resolve.
Presenting a report built from partial sources as if coverage were complete
Annotate which findings are well supported and which areas have gaps because sources were unavailable.
Sources
- Claude Developer Platform Docs
- Anthropic, Claude Certified Architect – Foundations Exam Guide v1.0 (July 2026)