# 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`
- **Domain:** python
- **Category:** runtime_error
- **Verification:** ai_generated
- **Fix Rate:** 80%

## 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.

## Version Compatibility

| Version | Status | Introduced | Deprecated |
|---------|--------|------------|------------|
| 3.8 | active | — | — |
| 3.9 | active | — | — |
| 3.10 | active | — | — |
| 3.11 | active | — | — |
| 3.12 | active | — | — |

## Workarounds

1. **** (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)
   ```
2. **** (95% success)
   ```
   Keep strong references and await tasks in a TaskGroup (3.11+):

async with asyncio.TaskGroup() as tg:
    tg.create_task(worker())
   ```
3. **** (85% success)
   ```
   For fire-and-forget, store tasks in a module-level set and remove in the callback to prevent GC.
   ```

## Dead Ends

- **** — Only adds more logging; the underlying exception is still lost. (70% fail)
- **** — Hides real bugs and still leaves the task result unretrieved. (80% fail)
- **** — Does not attach a handler to the task's exception. (85% fail)
