Files
hermes-agent/tools
salch-cred 1c82c22eb6 fix(mcp): skip dynamic tool refresh when the server session is already gone (#109824)
_refresh_tools called self.session.list_tools unguarded. run() resets
self.session to None on every transport teardown (clean reconnect,
error backoff, park, cancel) and the parked-probe path does the same,
none of it under _rpc_lock or _refresh_lock. A tools/list_changed
refresh scheduled on the dying transport therefore wakes up behind the
lock mid-restart and crashes the background task:

    ERROR tools.mcp_tool: MCP server 'treadmill': dynamic tool refresh failed
    AttributeError: 'NoneType' object has no attribute 'list_tools'

once per profile that includes the server, on every gateway restart with
a slow-to-connect MCP server.

Snapshot the session only once _rpc_lock is held and return at debug
level when it is None. The snapshot sits inside the RPC lock because
that is the point at which the refresh has actually won the right to
talk to the transport; a check before acquiring it can still observe a
session that teardown nulls while the refresh waits. Skipping is
correct, not a loss: the reconnect's own discovery re-lists and
re-registers tools, and the next tools/list_changed re-arms the refresh
against the live session. The previous registration stays intact rather
than being nuked mid-restart.

Co-authored-by: Tranquil-Flow <66773372+Tranquil-Flow@users.noreply.github.com>
Co-authored-by: ildunari <ildunari@users.noreply.github.com>
Co-authored-by: Andrex Ibiza <84248988+andrexibiza@users.noreply.github.com>
Co-authored-by: ly6751 <liuyu890412@gmail.com>
2026-09-17 19:06:29 -04:00
..