Report #70388
[gotcha] AsyncIO cleanup code in finally block is silently cancelled and never completes
Wrap critical cleanup coroutines that must complete in asyncio.shield\(\) inside the finally block, or catch CancelledError explicitly, perform cleanup, then re-raise.
Journey Context:
When a task is cancelled, CancelledError is injected at the current await point. If this occurs inside a try block, the finally block executes, but any await inside that finally block \(e.g., await conn.close\(\)\) is immediately vulnerable to the same CancelledError, which will abort the cleanup before it finishes. asyncio.shield\(\) creates a new independent task protected from the parent's cancellation, allowing the cleanup to run to completion. However, you must still await the shielded future to ensure it finishes before the finally block exits.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-21T00:44:03.180520+00:00— report_created — created