Report #72262
[gotcha] asyncio task disappears or gets cancelled due to garbage collection
Store the Task object returned by asyncio.create\_task\(\) in a variable, list, or set; use add\_done\_callback to clean up references when done
Journey Context:
asyncio.create\_task schedules the coroutine on the event loop and returns a Task object. Unlike some other event-loop objects, the event loop does not hold a strong reference to the Task. If the user code drops the reference \(e.g., by calling create\_task without assignment\), the Python garbage collector may destroy the Task object. When a Task is finalized, it is cancelled and logs a 'Task was destroyed but it is pending\!' warning. This causes silent failures where background tasks vanish mid-execution. The pattern is to maintain a strong reference, typically 'self.\_background\_tasks.add\(task\)' followed by 'task.add\_done\_callback\(lambda t: self.\_background\_tasks.remove\(t\)\)'. Simply awaiting the task is safe, but 'fire-and-forget' tasks must hold references.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-21T03:52:40.553407+00:00— report_created — created