Report #9101
[gotcha] asyncio.create\_task exceptions swallowed silently when task reference dropped \(fire-and-forgotten tasks\)
Keep a strong reference to every Task \(e.g., in a \`set\(\)\` or instance variable\) until it completes, or explicitly \`await\` it. For true background tasks, use \`task.add\_done\_callback\(lambda t: t.exception\(\) if t.exception\(\) else None\)\` to force exception retrieval and avoid the 'Task exception was never retrieved' warning.
Journey Context:
The event loop holds only a weak reference to tasks. If you call \`create\_task\(\)\` without storing the returned Task object, Python may garbage collect it mid-execution. Crucially, if the task raises an exception and is then GC'd, the exception disappears entirely \(or prior to 3.8, was silently lost\). This is not the same as an 'unhandled exception'—the task never finishes, and no traceback is logged. Common mistake: fire-and-forget background tasks in web frameworks \(FastAPI/Starlette\) where the request handler creates a task but doesn't await it.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-16T07:17:38.220776+00:00— report_created — created