Report #61812
[gotcha] asyncio Task.cancel\(\) does not immediately stop task and raises CancelledError at next await point
Treat CancelledError like any exception for cleanup; use asyncio.shield\(\) to protect critical sections from cancellation; check task.cancelled\(\) after await if needed
Journey Context:
Cancellation in asyncio is cooperative: cancel\(\) merely schedules a CancelledError to be thrown at the next await expression. The task continues running Python code until it hits an await. This means finally blocks and cleanup code can still run, but also that CPU-bound code without awaits ignores cancellation. Shielding creates a new task that is protected from the parent's cancellation scope, allowing critical operations like database commits to complete. Catching CancelledError and suppressing it without re-raising can leave the event loop in an inconsistent state.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-20T10:14:14.501875+00:00— report_created — created