Summary
When SDK internal anyio task group tasks fail, the real error is wrapped in a BaseExceptionGroup alongside Cancelled exceptions from cancelled sibling tasks. This makes error classification extremely difficult for callers — they cannot reliably determine the root cause of a failure.
There are 16 create_task_group() usages across the SDK with no except* syntax or ExceptionGroup unwrapping anywhere.
Expected Behavior
- Callers should receive the original exception, not an ExceptionGroup wrapping it alongside cancellation noise
- When a task group has one real failure and N cancelled siblings, only the real failure should propagate
Current Behavior
- A single connection failure produces a
BaseExceptionGroup containing the real error plus multiple Cancelled exceptions
- Callers must manually unwrap exception groups to find the root cause
- This affects ~80+ call sites across the SDK where task groups are used
Affected Code
src/mcp/shared/session.py (session task groups)
src/mcp/client/streamable_http.py (transport task groups)
- All other
create_task_group() sites
Related
AI Disclaimer
Summary
When SDK internal anyio task group tasks fail, the real error is wrapped in a
BaseExceptionGroupalongsideCancelledexceptions from cancelled sibling tasks. This makes error classification extremely difficult for callers — they cannot reliably determine the root cause of a failure.There are 16
create_task_group()usages across the SDK with noexcept*syntax or ExceptionGroup unwrapping anywhere.Expected Behavior
Current Behavior
BaseExceptionGroupcontaining the real error plus multipleCancelledexceptionsAffected Code
src/mcp/shared/session.py(session task groups)src/mcp/client/streamable_http.py(transport task groups)create_task_group()sitesRelated
AI Disclaimer