kyegomez/swarms

[Improvement] ConcurrentWorkflow aborts the whole run when any single agent fails

Open

#1613 aperta il 14 mag 2026

Vedi su GitHub
 (2 commenti) (0 reazioni) (0 assegnatari)Python (948 fork)github user discovery
FEATenhancementgood first issuehelp wanted

Metriche repository

Star
 (6809 star)
Metriche merge PR
 (Metriche PR in attesa)

Descrizione

Summary

In ConcurrentWorkflow, one failed agent kills the entire run and discards all sibling outputs that already completed successfully. This contradicts the design goal of independent concurrent execution.

Repro

from swarms import Agent, ConcurrentWorkflow

a = Agent(agent_name="Good-1", model_name="gpt-4.1", max_loops=1)
b = Agent(agent_name="Good-2", model_name="gpt-4.1", max_loops=1)
c = Agent(agent_name="Bad",    model_name="gpt-4.1", max_loops=1)
c.run = lambda *a, **kw: (_ for _ in ()).throw(RuntimeError("boom"))

wf = ConcurrentWorkflow(agents=[a, b, c])
wf.run("Summarise the news today.")
# Expected: results for Good-1 and Good-2, plus an error marker for Bad.
# Actual:   RuntimeError propagates out — Good-1 and Good-2's outputs are lost.

Root cause

swarms/structs/concurrent_workflow.py:418-425 does not wrap future.result() in a try/except:

for future in as_completed(futures):
    output = future.result()        # raises on any failed worker
    self.conversation.add(...)

The dashboard variant already handles this correctly at concurrent_workflow.py:346-356. The non-dashboard path was missed.

Proposed fix

Wrap future.result() in try/except mirroring the dashboard path. On error, append a clearly-labeled error entry to the conversation (e.g., role f"{agent_name} (failed)") so callers can filter it, and continue collecting sibling results.

Add an opt-in constructor flag for users who prefer the old behavior:

on_error: Literal["raise", "store"] = "store"

"store" (default) collects per-agent errors and returns partial results. "raise" preserves today's fail-fast behavior.

Tests to add

  • ConcurrentWorkflow with one failing agent and two passing agents: assert partial results returned, failed agent's error captured under its name, no exception escapes.
  • on_error="raise": assert the exception still propagates.

Guida contributor