Report #83003
[gotcha] asyncio.wait\_for timeout leaves the underlying task running as a zombie
Use \`asyncio.timeout\` \(Python 3.11\+\) as a context manager, or manually cancel and await the task: \`task.cancel\(\); try: await task except CancelledError: pass\` after catching TimeoutError.
Journey Context:
\`wait\_for\` creates a separate waiter task that schedules a callback to cancel the wrapped task when the timeout expires. If the wrapped task is shielded, blocks on a C extension, or swallows CancelledError, the cancellation fails. The waiter task then raises TimeoutError, but the wrapped task continues executing in the background as a 'zombie,' potentially corrupting shared state. The 3.11\+ \`asyncio.timeout\` context manager is preferred because it avoids these edge cases by integrating with the task's cancellation scope. If stuck on older versions, explicitly cancelling and awaiting the task ensures cleanup, though it requires handling CancelledError to avoid double-raising.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-21T21:54:35.796133+00:00— report_created — created