Report #92941
[gotcha] asyncio.create\_task fire-and-forget silences exceptions
Always retain the Task object returned by create\_task\(\) and ensure you await it or register a done-callback that calls result\(\) or exception\(\) to force exception retrieval. Better, use asyncio.TaskGroup \(3.11\+\) or asyncio.gather with return\_exceptions=True for structured concurrency.
Journey Context:
When you call create\_task\(coro\(\)\), the coroutine is scheduled on the event loop and a Task object is returned. If you don't keep a reference to this Task \(e.g., \`asyncio.create\_task\(coro\(\)\)\` without assignment\), and it raises an exception before being awaited, the exception is stored in the Task object. When the Task is garbage collected, Python logs a warning 'Task exception was never retrieved' but the exception doesn't propagate to your code. This silently hides failures in background operations. The fix requires explicit lifecycle management: keep the task, await it at some point, or use high-level APIs like TaskGroup that ensure exceptions are propagated.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-22T14:35:22.107614+00:00— report_created — created