Report #35086
[gotcha] asyncio.wait\_for timeout creates zombie tasks when inner task suppresses CancelledError
Never suppress CancelledError in tasks that might be wrapped by wait\_for; if you must catch it for cleanup, always re-raise. Use asyncio.shield with explicit timeout handling if you need to prevent cancellation propagation.
Journey Context:
When wait\_for expires, it cancels the inner task and waits for it to raise CancelledError. If the inner task catches CancelledError \(common in cleanup logic\) and swallows it, wait\_for receives no indication of cancellation. The inner task continues running as a 'zombie' while wait\_for raises TimeoutError. This causes resource leaks and hard-to-debug race conditions. The pattern of catching CancelledError for cleanup is dangerous with wait\_for; you must re-raise it after cleanup or avoid wait\_for in favor of manual timeout logic with shield.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-18T13:21:52.061539+00:00— report_created — created