Skip to content

fix(binding-mcp): settle a still-establishing toolkit client on reset/abort - #2427

Merged
jfallows merged 1 commit into
developfrom
fix/mcp-lifecycle-settle-on-reset
Aug 25, 2026
Merged

fix(binding-mcp): settle a still-establishing toolkit client on reset/abort#2427
jfallows merged 1 commit into
developfrom
fix/mcp-lifecycle-settle-on-reset

Conversation

@jfallows

Copy link
Copy Markdown
Contributor

Description

An mcp(client)-backed session's south connections toward each routed toolkit are established eagerly and in parallel; the north-facing session's own accept is deferred until every one of them settles (either by opening successfully or by being told to settle explicitly).

McpLifecycleClient's onClientAbort/onClientReset only told the session to settle when hydration was in progress and this client had never opened -- any other combination propagated the abort/reset to the session. That condition had no else branch, so exactly that one case did neither: a hydration session's still-establishing toolkit resetting or aborting left the session waiting on a settlement that would now never arrive, wedging the whole hydration attempt indefinitely.

Both handlers now call settleLifecycle for that case instead of doing nothing, letting the session proceed without that toolkit; the existing per-kind retry/backoff already re-attempts it once the session is no longer blocked. A caller's own (non-hydration) session and an already-established toolkit's later failure keep propagating exactly as before.

Validated end-to-end against a two-node cluster with a hydration-backed cache: reproduced the wedge (a node became unresponsive to every new session once a toolkit reset mid-establishment), confirmed the fix resolves it (hydration completes and the node stays responsive across repeated fresh restarts), and confirmed initialize responses and per-kind cache recovery are unaffected for every other case.

./mvnw -pl runtime/binding-mcp -am test passes (178 tests, 0 failures/errors).

Fixes # (issue)


Generated by Claude Code

…/abort

An mcp(client)-backed session's south connections toward each routed
toolkit are established eagerly and in parallel; the north-facing
session's own accept is deferred until every one of them settles (either
by opening successfully or by being told to settle explicitly).

McpLifecycleClient's onClientAbort/onClientReset only told the session to
settle when hydration was in progress AND this client had never opened --
any other combination propagated the abort/reset to the session. That
condition had no else branch, so exactly that one case did neither:
a hydration session's still-establishing toolkit resetting or aborting
left the session waiting on a settlement that would now never arrive,
wedging the whole hydration attempt indefinitely.

Both handlers now call settleLifecycle for that case instead of doing
nothing, letting the session proceed without that toolkit; the existing
per-kind retry/backoff already re-attempts it once the session is no
longer blocked. A caller's own (non-hydration) session and an
already-established toolkit's later failure keep propagating exactly as
before.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01W7N8Z9vABdU8pVPGthRodY

@jfallows jfallows left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@jfallows
jfallows merged commit e5d01fc into develop Aug 25, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants