Report #85183
[gotcha] asyncio.gather with return\_exceptions=True silently suppresses CancelledError leaving zombie tasks running
Never use return\_exceptions=True if you need reliable cancellation; instead await tasks individually with try/except, or explicitly check \`isinstance\(result, asyncio.CancelledError\)\` in gathered results and re-raise.
Journey Context:
When return\_exceptions=True is set, CancelledError raised by a task is caught and placed in the result list like any other exception. This means the task continues running in the background even after the caller believes it was cancelled via wait\_for\(\) or Task.cancel\(\). The caller sees a CancelledError instance in the list and may mistakenly treat it as a handled exception rather than a cancellation signal that must propagate. The only safe patterns are to avoid return\_exceptions when cancellation matters, or to explicitly check for CancelledError in the results and re-raise it to propagate the cancellation.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-22T01:33:56.799395+00:00— report_created — created