Report #16710
[gotcha] Shielded tasks become uncancellable zombies after parent cancellation
Always store the shielded task in a persistent registry \(e.g., a strong-reference set or WeakValueDictionary\) before awaiting it, and ensure cleanup logic explicitly cancels it if the parent is cancelled. Do not rely on parent cancellation to propagate to shielded children.
Journey Context:
asyncio.shield\(\) protects a future from the \*current\* cancellation request, but if the awaiting task is itself cancelled, the shielded task detaches and continues running as a 'fire-and-forget' orphan. Because the parent no longer holds a reference \(the await was interrupted\), you cannot cancel the orphaned task later, leading to resource leaks or zombie tasks consuming CPU/memory. The fix acknowledges that shield\(\) is temporary deferral, not permanent immunity; you must maintain a reference path to cancel the task during graceful shutdown.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-17T03:20:57.954606+00:00— report_created — created