Description
When the parent asyncio task calling query() is cancelled (e.g., user presses Stop, or cleanup calls task.cancel() + await task), the anyio cancel scope inside the SDK raises:
RuntimeError: Attempted to exit cancel scope in a different task than it was entered in
Stack trace
File ".../claude_agent_sdk/_internal/client.py", line 139, in process_query
async for data in query.receive_messages():
...
File ".../anyio/_backends/_asyncio.py", line 794, in __aexit__
return self.cancel_scope.__exit__(exc_type, exc_val, exc_tb)
File ".../anyio/_backends/_asyncio.py", line 461, in __exit__
raise RuntimeError(
RuntimeError: Attempted to exit cancel scope in a different task than it was entered in
Reproduction
- Start a
query() call inside an asyncio.create_task()
- From a different context, cancel that task:
task.cancel(); await task
- The SDK's
query.close() → self._tg.__aexit__() raises the RuntimeError
Expected behavior
Cancellation should propagate cleanly without RuntimeError. The cancel scope should detect cross-task cancellation and handle it gracefully.
Environment
claude-agent-sdk==0.1.50
- Python 3.12
- anyio (latest)
Description
When the parent asyncio task calling
query()is cancelled (e.g., user presses Stop, or cleanup callstask.cancel()+await task), the anyio cancel scope inside the SDK raises:Stack trace
Reproduction
query()call inside anasyncio.create_task()task.cancel(); await taskquery.close()→self._tg.__aexit__()raises the RuntimeErrorExpected behavior
Cancellation should propagate cleanly without RuntimeError. The cancel scope should detect cross-task cancellation and handle it gracefully.
Environment
claude-agent-sdk==0.1.50