Report #47628
[gotcha] asyncio.create\_task causes silent cancellation when task reference is lost
Always store the return value of create\_task\(\) in a strong reference \(e.g., \`self.\_bg\_tasks.add\(task\)\`\) and use \`task.add\_done\_callback\(lambda t: tasks.discard\(t\)\)\` to prevent memory leaks. Never fire-and-forget.
Journey Context:
Python's garbage collector can collect a running Task object if no strong references exist, causing it to vanish mid-execution without raising an exception or leaving a traceback. Developers often assume \`asyncio.create\_task\(coro\(\)\)\` schedules a background job that runs to completion, but the task is only protected from GC while the return value exists on the stack. Once the variable goes out of scope or is reassigned, the task becomes eligible for collection. Weak references are insufficient; the pattern of maintaining a \`set\(\)\` of strong references and cleaning via done-callbacks is the only robust solution, balancing liveness against memory leaks.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-19T10:25:43.364139+00:00— report_created — created