LOW SEVERITYCONFIRMED
_execute_single_listener exceptions swallowed by asyncio.gather — non-deterministic flow state
Package
crewai
Version
HEAD
Verified
2026-03-28
Description
crewai's `_execute_racing_and_other_listeners` calls `asyncio.gather(*other_tasks, return_exceptions=True)`, which silently discards exceptions from non-racing listeners. If a listener raises after partial side effects, `_completed_methods` is not updated and the flow continues as though that listener never ran. Given the same event and state, two runs can produce different `_completed_methods` sets depending on whether a transient error occurred.
Reproduction
# A Flow listener that raises on first call:
# Run 1: listener raises -> exception swallowed -> listener not in _completed_methods
# Run 2: listener succeeds -> listener in _completed_methods
# Same initial state, different outcomes — non-determinism under error conditions