Skip to content

Resource Leak: anyio memory object stream associated with a query is leaked #859

@dave-shawley

Description

@dave-shawley

Query.close() cancels the task group and closes the transport but leaves other resources uncleaned. The memory object stream objects are reported as leaked from the following simple reproduction script when run with PYTHONDEVMODE defined. This is likely fixed by #657. I decided to create the issue to boost awareness.

#!/usr/bin/env python3
"""
Reproduces the ResourceWarning for unclosed anyio memory streams in Query.close().

Query.close() cancels the read task and closes the transport but never calls
aclose() on self._message_send or self._message_receive (the anyio
MemoryObjectSendStream / MemoryObjectReceiveStream pair created in __init__).
Those objects are collected by the GC with their streams still open.

Usage:
    PYTHONDEVMODE=1 python repro_stream_leak.py

Expected warnings:
    ResourceWarning: Unclosed <MemoryObjectReceiveStream ...>
    ResourceWarning: Unclosed <MemoryObjectSendStream ...>
"""
import asyncio
import gc

import claude_agent_sdk


async def main() -> None:
    async with claude_agent_sdk.ClaudeSDKClient() as client:
        await client.query("Reply with the single word: hello")
        async for _message in client.receive_response():
            pass


asyncio.run(main())

# Force GC so the warnings are emitted during the script rather than at
# interpreter shutdown, where they can be swallowed or harder to attribute.
gc.collect()

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions