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) flows back to the coordinator. That flow 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.

A bricklaying firm uses a multi-agent system to prepare quotes. Five subagents look up brick prices, mortar and sand prices, the job calendar, past jobs with similar walls, and the customer's order history. The brick price subagent times out.

Structured Error Context

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

1. Failure type. Transient failures (a timeout, a rate limit) may succeed on retry. Validation failures (bad input) need the query fixed. Business failures (a rule violation) need escalation or an alternative. Permission failures (access denied) cannot be retried without authorisation changes. The brick 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 merchant's price list for 'red facing brick', June delivery" is actionable. "Search failed" is not.

3. Partial results gathered before failure. If the subagent retrieved three of five sources before timing out, those three 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: a second merchant, say, or last week's prices. 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 bricklayer's coordinator could use its three brick prices and retry the rest.

The Two Anti-Patterns

Both 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 won't retry or try alternatives. Its synthesis silently omits an entire area. The output looks complete but is missing critical content: the bricklayer's quote goes out with no brick cost.

Silent suppression is especially dangerous because it's invisible: nobody can detect the gaps. In customer support, the firm's agent may report "no orders found" while the order lookup is down, then tell the customer they have no account.

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 thrown away. This disproportionate response wastes completed work and gives no recovery path. The bricklayer loses four finished lookups to one slow merchant.

The middle ground is structured error propagation: the subagent reports what happened, the coordinator assesses the damage, and the system continues with partial results or targeted recovery.

Access Failure vs Valid Empty Result

Access failure: The tool could not reach the data source, through 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 is the answer, and no retry is needed because the system worked correctly. No curved garden walls in the past-jobs records means the firm has not built one.

Conflating the two 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 brick subagent failed, the quote summary should say so.

"Section on brick costs is limited because the merchant price list was unavailable."

This is far better than silently omitting the topic. Coverage annotations tell the consumer 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, degraded responses) before propagating errors. Only propagate errors the subagent can't resolve locally, and always include what was attempted and any partial results.

This reduces coordinator complexity. Each subagent handles its own transient failures and escalates only persistent ones, so the coordinator need not manage retry logic for every subagent. The brick subagent retries the merchant, tries a second one, and reports only if both 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 stem describes a subagent timeout, the keyed answer returns structured error context so the coordinator can decide how to recover.

Key Concept

Structured error context enables intelligent coordinator recovery. Avoid silent suppression and workflow termination. Access failures need retry consideration; 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, while successful queries returning 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) 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 survive 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 blanket policies. This is the correct middle ground between 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