python
runtime_error
ai_generated
true
Task exception was never retrieved future: <Task finished name='Task-5' coro=<worker() done, defined at app.py:42> exception=ValueError('bad payload')>
ID: python/task-exception-never-retrieved
80%Fix Rate
89%Confidence
0Evidence
2024-08-02First Seen
Version Compatibility
| Version | Status | Introduced | Deprecated | Notes |
|---|---|---|---|---|
| 3.8 | active | — | — | — |
| 3.9 | active | — | — | — |
| 3.10 | active | — | — | — |
| 3.11 | active | — | — | — |
| 3.12 | active | — | — | — |
Root Cause
A task created with asyncio.create_task() raised an exception, but no one awaited the task or attached a done callback, so the exception is discarded.
generic中文
通过 asyncio.create_task() 创建的任务抛出异常,但没有人 await 该任务或附加完成回调,因此异常被丢弃。
Workarounds
-
90% success
Attach a done callback that logs exceptions: def _log(task): if (exc := task.exception()): logger.exception('task failed', exc_info=exc) task = asyncio.create_task(worker()) task.add_done_callback(_log) -
95% success
Keep strong references and await tasks in a TaskGroup (3.11+): async with asyncio.TaskGroup() as tg: tg.create_task(worker()) -
85% success
For fire-and-forget, store tasks in a module-level set and remove in the callback to prevent GC.
Dead Ends
Common approaches that don't work:
-
70% fail
Only adds more logging; the underlying exception is still lost.
-
80% fail
Hides real bugs and still leaves the task result unretrieved.
-
85% fail
Does not attach a handler to the task's exception.