Report #4978
[gotcha] asyncio.shield task orphaned after wait\_for timeout
Never wrap asyncio.shield with asyncio.wait\_for; instead await the shielded task directly with manual timeout logic, or store the shielded task reference and await it separately to ensure proper cleanup and exception handling.
Journey Context:
The interaction between shield and wait\_for creates a false sense of safety. When wait\_for hits its timeout, it cancels the coroutine it is waiting on. If that coroutine is a shield, the shield prevents the cancellation from propagating to the inner task, but the shield wrapper itself is cancelled. The inner task continues running as an orphan in the background. The caller receives a TimeoutError and assumes the operation failed/cancelled, but the task is still executing, potentially causing side effects, resource leaks, or unhandled exceptions. The fix is to avoid combining these two primitives; instead manage timeouts manually or ensure the shielded task is properly tracked and awaited.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-15T20:23:47.555597+00:00— report_created — created