Description
plugins/memory/honcho/client.py exposes get_honcho_client() — a lazy-init accessor for the process-wide _honcho_client singleton (line 665–776). The check-before-init pattern is:
_honcho_client: Honcho | None = None
def get_honcho_client(config=None) -> Honcho:
global _honcho_client
if _honcho_client is not None:
return _honcho_client
# ... full config resolution + lazy SDK install ...
_honcho_client = Honcho(**kwargs)
return _honcho_client
There is no lock around the check-then-initialize sequence. When two threads call get_honcho_client() concurrently before the singleton is set, both pass the is not None guard, both run the expensive initialization (config loading, optional lazy SDK install, Honcho(**kwargs) construction), and the second write overwrites the first — leaving an open connection leaked.
Impact
In multi-threaded agent sessions sharing one process (e.g. delegated tool calls, background workers), Honcho clients can be constructed multiple times, leaking connections and causing non-deterministic behavior if the first client established state (e.g. session contexts) that the replacement doesn't know about.
Fix
Add import threading, _honcho_client_lock = threading.Lock(), and apply double-checked locking in get_honcho_client().
Description
plugins/memory/honcho/client.pyexposesget_honcho_client()— a lazy-init accessor for the process-wide_honcho_clientsingleton (line 665–776). The check-before-init pattern is:There is no lock around the check-then-initialize sequence. When two threads call
get_honcho_client()concurrently before the singleton is set, both pass theis not Noneguard, both run the expensive initialization (config loading, optional lazy SDK install,Honcho(**kwargs)construction), and the second write overwrites the first — leaving an open connection leaked.Impact
In multi-threaded agent sessions sharing one process (e.g. delegated tool calls, background workers), Honcho clients can be constructed multiple times, leaking connections and causing non-deterministic behavior if the first client established state (e.g. session contexts) that the replacement doesn't know about.
Fix
Add
import threading,_honcho_client_lock = threading.Lock(), and apply double-checked locking inget_honcho_client().