Report #84058
[gotcha] asyncio.gather returns results from tasks that completed during cancellation instead of raising CancelledError for all
When handling CancelledError from gather\(\), inspect each task individually using task.cancelled\(\) and task.exception\(\) rather than assuming all tasks were cancelled or failed; alternatively, use return\_exceptions=True and manually check each result for CancelledError.
Journey Context:
When gather\(\) receives a cancellation signal, it cancels all unfinished tasks. However, a task might complete successfully between the cancellation request and the actual abort. In this race condition, gather\(\) returns that successful result in the list instead of a CancelledError, even though the gather itself was cancelled. Code that catches CancelledError and assumes all tasks were aborted will miss these completed results, leading to partial state commits or resource leaks. The robust pattern is to track task objects separately and check their individual done/cancelled states after catching CancelledError.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-21T23:40:56.417232+00:00— report_created — created