# asyncio.exceptions.CancelledError: Task was destroyed but it is pending!

- **ID:** `python/asyncio-gather-cancelled-error`
- **Domain:** python
- **Category:** runtime_error
- **Verification:** ai_generated
- **Fix Rate:** 80%

## Root Cause

When using asyncio.gather() with return_exceptions=False, if one task raises CancelledError (e.g., due to timeout), the gather is cancelled and other tasks are not properly awaited, leading to pending task destruction warnings.

## Version Compatibility

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

## Workarounds

1. **** (90% success)
   ```
   results = await asyncio.gather(*tasks, return_exceptions=True)
for r in results:
    if isinstance(r, asyncio.CancelledError):
        # handle cancellation gracefully
   ```
2. **** (85% success)
   ```
   done, pending = await asyncio.wait(tasks, return_when=asyncio.FIRST_EXCEPTION)
for task in pending:
    task.cancel()
await asyncio.gather(*pending, return_exceptions=True)
   ```

## Dead Ends

- **** — CancelledError is not always raised synchronously; it can be raised during await, and ignoring it may leave tasks in inconsistent states. (60% fail)
- **** — Shield only protects against cancellation of the outer task, not the inner tasks; it doesn't solve the root issue of pending tasks. (70% fail)
