[Improvement] ConcurrentWorkflow aborts the whole run when any single agent fails
#1,613 opened on May 14, 2026
Repository metrics
- Stars
- (6,809 stars)
- PR merge metrics
- (PR metrics pending)
Description
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
ConcurrentWorkflowwith 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.