AI & Agent Dev Bug Sandbox logo
AI & Agent Dev Bug Sandbox
Back to Radar

ChatOpenRouter Leaks Httpx.AsyncClient Instances Causing Ephemeral Port Exhaustion

The ChatOpenRouter class in langchain-openrouter creates a new httpx.Client and httpx.AsyncClient on every instantiation without providing a close/context manager, leading to unclosed sockets and eventually ephemeral port exhaustion under high concurrency.

highConfidence 92%Langchain

Origin Analysis

In `_build_client()`, the method instantiates `httpx.AsyncClient` (and `httpx.Client`) every time `ChatOpenRouter` is created, but the class lacks `close()`, `aclose()`, `__del__`, or context manager support to release these resources. The default `app_url` and `app_title` parameters trigger `extra_headers` logic, ensuring new clients are always created.
Run the provided reproduction script: instantiate 100 ChatOpenRouter objects in a loop without explicitly closing them; monitor open connections with psutil; resources accumulate because no teardown is called.

Fixing Code Block

Edge Case Audit

Closing the client while other coroutines are still using the same instance may cause RuntimeError or premature connection termination. In multi-threaded or concurrent async tasks, use a shared client or synchronize access; avoid calling __del__ as it is not guaranteed to run and may cause issues during interpreter shutdown. Rollback: if this fix introduces inconsistent client states, revert to previous behavior and advise users to pass a shared httpx.AsyncClient or use a global pool.

Ecosystem Topology