# ExceptionGroup: unhandled errors in a TaskGroup (1 sub-exception)

- **ID:** `python/asyncio-taskgroup-exceptiongroup`
- **Domain:** python
- **Category:** runtime_error
- **Verification:** ai_generated
- **Fix Rate:** 80%

## Root Cause

An exception inside asyncio.TaskGroup (3.11+) is wrapped in an ExceptionGroup; callers that catch the original exception type never see it.

## Version Compatibility

| Version | Status | Introduced | Deprecated |
|---------|--------|------------|------------|
| 3.11 | active | — | — |
| 3.12 | active | — | — |

## Workarounds

1. **** (95% success)
   ```
   Catch ExceptionGroup and use except*:

try:
    async with asyncio.TaskGroup() as tg:
        tg.create_task(work())
except* ValueError as eg:
    handle(eg.exceptions)
   ```
2. **** (90% success)
   ```
   Inspect sub-exceptions:

except ExceptionGroup as eg:
    for exc in eg.exceptions:
        logger.error('task failed', exc_info=exc)
   ```
3. **** (85% success)
   ```
   For libraries that don't support except*, unwrap manually:

def unwrap(eg): return eg.exceptions[0] if len(eg.exceptions) == 1 else eg
   ```

## Dead Ends

- **** — The ValueError is nested inside ExceptionGroup; the outer except never matches. (90% fail)
- **** — Swallows the group but is bad practice; masks other failures. (70% fail)
- **** — Touches private state; unrelated to exception wrapping. (95% fail)
