Skip to content
Domain 5Task 5.3

Error Propagation in Multi-Agent Systems

Learn this interactively

What You Need to Know

In a multi-agent system, a coordinator hands tasks to subagents and combines their results. Error propagation is how a subagent's failure (a timeout, a permission error, an invalid query) reaches the coordinator. This propagation decides whether the system recovers gracefully or fails silently. An access failure means a tool never reached its data. A valid empty result means the tool reached the data, ran the query and found nothing.

This lesson uses one example throughout, based on the exam guide's multi-agent research system, which writes research reports. For a report on renewable energy policy, five subagents each search a different source. The subagent that searches an academic database times out.

Structured Error Context

A failing subagent must return structured error context with four elements. This is because the coordinator can only make an intelligent decision about recovery from what the subagent tells it.

1. Failure type. Transient failures (a timeout, a rate limit) may succeed on retry. A rate limit is a cap on how many requests a service accepts in a set time. Validation failures (bad input) need a corrected query. Business failures (a rule violation) need escalation or an alternative. Permission failures (access denied) cannot be retried without authorisation changes. The academic database timeout is transient.

2. What was attempted. Give the specific query, parameters and target system. The coordinator cannot adjust a query it cannot see. "Searched the academic database for 'renewable energy policy', 2022 to 2024" is actionable. "Search failed" is not.

3. Partial results gathered before failure. If the subagent retrieved some results before timing out (one document in the example below), those results are still useful. Discarding them because the operation failed is wasteful.

4. Potential alternative approaches. The subagent knows its domain, so it can suggest a different source, broader search terms or cached results. The example below suggests a narrower date range, a second database and cached results. These suggestions help the coordinator choose a recovery strategy.

json
{
  "status": "partial_failure",
  "failureType": "transient",
  "attemptedAction": {
    "tool": "search_academic_db",
    "query": "renewable energy policy",
    "dateRange": "2022-2024"
  },
  "partialResults": [
    {
      "title": "EU Renewable Energy Directive 2023",
      "source": "EUR-Lex",
      "retrieved": true
    }
  ],
  "alternativeApproaches": [
    "Retry with narrower date range (2023-2024)",
    "Search alternative database: government_publications",
    "Use cached results from previous research session"
  ]
}

After a subagent timeout, this structure gives the coordinator what it needs to decide: retry the same query, try an alternative, proceed with partial results or escalate. The research coordinator could keep the one partial result and search the government_publications database.

The Two Anti-Patterns

Both anti-patterns, which are common approaches that do not work, are catastrophic, in different ways.

Silent suppression: returning empty results marked as success. This is the worst anti-pattern. The subagent times out but returns { "results": [], "status": "success" }. The coordinator believes the search ran and found nothing, so it will not retry or try alternatives. The coordinator's synthesis silently omits an entire area. The output looks complete but is missing critical content: the report has no academic sources.

Silent suppression is especially dangerous because it is invisible: nobody can detect the gaps. A reader of the research report cannot see that the academic database never answered.

Workflow termination: killing the entire pipeline on a single failure. One subagent times out and the whole pipeline crashes. The other four completed successfully, but their results are discarded. This disproportionate response wastes completed work and gives no way to recover. The research system loses four finished searches because one database is slow.

The approach that avoids both anti-patterns is structured error propagation. The subagent reports what happened. The coordinator assesses the effect of the failure. The system continues with partial results or with targeted recovery.

Access Failure vs Valid Empty Result

Access failure: The tool could not reach the data source because of a timeout, a connection error or a permission denial. The search did not execute. Consider retrying with the same or modified parameters.

Valid empty result: The tool reached the source, executed the query and found no matches. That result is the answer, and no retry is needed because the system worked correctly. When the academic database holds no papers that match the query, this result is the true answer: there are none to find.

Confusing access failures with valid empty results causes two problems.

  • Treating access failures as valid empty results means you never retry when you should.
  • Treating valid empty results as access failures means you waste time retrying a query that will always return nothing.
python
# Access failure — consider retry
{
    "status": "error",
    "failureType": "transient",
    "message": "Connection timeout after 30s",
    "shouldRetry": True
}

# Valid empty result — no retry needed
{
    "status": "success",
    "results": [],
    "message": "Query executed successfully. No matching records found.",
    "shouldRetry": False
}

Coverage Annotations

When a synthesis agent combines subagent findings, the output should note which topic areas are well supported and which have gaps. If the academic database search failed, the report should say so.

"Section on academic studies is limited because the academic database was unavailable."

A coverage annotation like this is far better than silently omitting the topic. Coverage annotations tell the consumer of the output what is fully covered and where the known limitations are. Without them, a gap looks like an irrelevant topic, not an unavailable source.

Local Recovery for Transient Failures

Subagents should recover locally from transient failures (retry logic, fallback sources, lower-quality responses) before propagating errors. Only propagate errors the subagent cannot resolve locally, and always include what the subagent attempted and any partial results.

Local recovery reduces the complexity of the coordinator. Each subagent handles its own transient failures and escalates only persistent ones, so the coordinator need not manage retry logic for every subagent. The academic database subagent retries its search and reports the timeout only if the retries also fail.

In the exam

The exam tests structured error context, the two anti-patterns (explicitly) and access failures versus valid empty results (directly). Most developers get that last distinction wrong. When a question describes a subagent timeout, the right answer has the subagent return structured error context. This context lets the coordinator decide how to recover.

Key Concept

Structured error context lets the coordinator recover intelligently. Avoid silent suppression and workflow termination. Access failures need you to consider a retry. Valid empty results do not.

Exam Traps

Exam Trap

Catching a timeout and returning empty results marked as successful

The coordinator believes the search succeeded and found nothing, so it does not attempt alternatives. Return structured error context (failure type, attempted query, partial results, alternatives) so the coordinator can retry or proceed with partial results.

Exam Trap

Terminating the entire research pipeline when one subagent times out

Workflow termination wastes partial results from other subagents that completed successfully. The coordinator should assess the failure and decide on targeted recovery.

Exam Trap

Returning a generic 'search unavailable' status after retry exhaustion

Generic errors hide the query, partial results, and alternative approaches from the coordinator. Structured error context enables informed recovery; generic statuses prevent it.

Exam Trap

Retrying a valid empty result because it looks like a failure

A valid empty result means the query executed successfully and found no matches. This IS the answer. Retrying wastes time and resources on a query that will always return nothing.

Practice Scenario

A web search subagent in a multi-agent research system times out while researching a complex topic. You need to design how this failure information flows back to the coordinator. Which approach best enables intelligent recovery?

Build Exercise

Build Exercise

Build a Structured Error Propagation System

Difficulty
50 minutes

What you'll learn

  • Design structured error context with the four required elements: failure type, attempted action, partial results, and alternative approaches
  • Distinguish access failures (timeout, connection error) from valid empty results (successful query, no matches)
  • Identify and avoid the two anti-patterns: silent suppression and workflow termination
  • Implement local retry logic for transient failures before propagating to the coordinator
  • Add coverage annotations to synthesis output for transparency about information gaps
  1. Define a structured error schema with fields: failureType (transient/validation/business/permission), attemptedAction (tool, query, parameters), partialResults (array of any retrieved data), and alternativeApproaches (suggested recovery strategies)

    Why: Structured error context enables intelligent coordinator recovery. The four elements give the coordinator everything it needs to decide: retry, try an alternative, proceed with partial results, or escalate. Generic error messages like search unavailable prevent all informed recovery.

    You should see: A TypeScript interface or JSON schema with failureType as an enum of the four categories, attemptedAction as an object with tool/query/parameters, partialResults as an array, and alternativeApproaches as a string array. Each field should have a description explaining its purpose.

  2. Implement a subagent that distinguishes access failures (timeout, connection error) from valid empty results (successful query, no matches) in its error reporting

    Why: Conflating access failures with valid empty results is a critical error the exam tests directly. Access failures mean the query did not execute and should be retried. Valid empty results mean the query succeeded and found nothing, which IS the answer. Treating them the same leads to either never retrying when you should or wasting time retrying queries that will always return nothing.

    You should see: A subagent function that catches exceptions (timeouts, connection errors) and reports them as access failures with shouldRetry: true. Successful queries that return no results are reported as success, with an empty results array and shouldRetry: false.

  3. Build local retry logic for transient failures within the subagent (3 retries with exponential backoff, where the wait doubles after each failed attempt) before propagating to the coordinator

    Why: Subagents should handle their own transient failures locally before escalating. This reduces coordinator complexity as the coordinator does not need to manage retry logic for every possible transient failure across every subagent. Only persistent failures that remain after local retry should propagate.

    You should see: A retry wrapper with exponential backoff (e.g., 1s, 2s, 4s) that attempts the operation up to 3 times before propagating the structured error to the coordinator. Partial results gathered before failure should be preserved across retries.

  4. Create a coordinator that receives structured errors and decides between retry with modified query, alternative approach, or proceed with partial results

    Why: The coordinator is the intelligent recovery decision-maker. With structured error context, it can make informed choices rather than applying one rule to every failure. This is the correct approach that avoids both silent suppression (ignoring failures) and workflow termination (killing the pipeline on one failure).

    You should see: A coordinator function that examines the failure type, checks partial results, evaluates alternative approaches, and selects the appropriate recovery strategy. It should handle all four failure types differently and never silently suppress errors.

  5. Add coverage annotations to synthesis output noting which findings are well-supported versus which topic areas have gaps due to unavailable sources

    Why: Coverage annotations let the consumer know what the report covers fully and where there are known limitations. Without them, a gap looks like the topic was not relevant rather than the source being unavailable. This transparency is far better than silently omitting topics.

    You should see: A synthesis output that includes a coverage section listing each topic area with its data quality status: well-supported, limited (with reason), or unavailable (with reason). Failed subagent topics should be explicitly noted, not silently omitted.

Sources