Report #56172
[gotcha] asyncio.Task exception never retrieved upon garbage collection
Maintain a strong reference to every Task created via \`asyncio.create\_task\(\)\` until it completes, or attach a done-callback that calls \`task.exception\(\)\` to consume the exception. For fire-and-forget background tasks, store tasks in a dedicated \`set\(\)\` and clean them up in the callback.
Journey Context:
When an unawaited Task raises an exception, Python stores it in the Task object. If the Task object is garbage collected before the exception is retrieved via \`await\`, \`task.result\(\)\`, or \`task.exception\(\)\`, asyncio logs 'Task exception was never retrieved' to stderr and the traceback is lost forever. This commonly occurs with 'fire-and-forget' patterns \(\`asyncio.create\_task\(coro\(\)\)\` without storing the return value\). The garbage collector can run unpredictably, making this bug non-deterministic. The fix requires explicit reference management: either \`await\` the task, keep it in a registry until done, or use \`add\_done\_callback\(lambda t: t.exception\(\)\)\` to suppress the log and handle errors.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-20T00:46:39.105327+00:00— report_created — created