Skip to content

fix(client): handle cleanup rejection after initialization failure - #2770

Open
koenvg wants to merge 1 commit into
modelcontextprotocol:v1.xfrom
koenvg:fix/client-connect-cleanup-rejection
Open

fix(client): handle cleanup rejection after initialization failure#2770
koenvg wants to merge 1 commit into
modelcontextprotocol:v1.xfrom
koenvg:fix/client-connect-cleanup-rejection

Conversation

@koenvg

@koenvg koenvg commented Sep 8, 2026

Copy link
Copy Markdown

Summary

Handle rejection from the SDK-owned Client.close() call when initialization fails. Keep cleanup non-blocking and preserve the original initialization error.

Targets the maintained v1.x branch. The issue is present in SDK 1.29.0 and remains in 1.30.0.

Problem

Client.connect() catches an initialization error and calls void this.close() before rethrowing it. If close() rejects, that separate promise is unhandled even when the application catches the original connection failure. Under Node's strict rejection handling, the cleanup failure can terminate the process.

The regression uses the real Client and Streamable HTTP transport, a controlled failing initialization fetch, and a rejecting close mock. It reproduces an SDK-owned cleanup rejection, not a caller's subsequent cleanup failure.

Change

  • Attach a rejection handler to the SDK-owned cleanup promise.
  • Do not await cleanup, change connection-failure timing, or replace the original error with the cleanup error.
  • Add strict Node subprocess regressions for immediate rejection, deferred rejection, successful cleanup, and pending cleanup.
  • Include a patch changeset.

Before the fix, both rejection scenarios fail with an uncaught cleanup error; both controls pass. After the fix, all four pass. Tests also check the original error by identity and that initialization and cleanup each run once.

Validation

  • npm test -- test/client/connect-cleanup.test.ts test/client/index.test.ts: 72 passed.
  • npm test: 1,651 passed across 53 files.
  • npm run typecheck: passed.
  • npm run lint: passed.
  • npm run build: ESM and CJS passed.
  • Downstream verification against a locally built package: four ClassSpotter initialization subprocess regressions and 13 existing caller-cleanup tests passed. These additionally verify bounded diagnostics and failed-call semantics for discovery and search.

No installed dependency files were edited, no package versions were changed, and no package was published. Fresh-context read-only review found no issues.

@koenvg
koenvg requested a review from a team as a code owner September 8, 2026 19:18
@changeset-bot

changeset-bot Bot commented Sep 8, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: cd3ed36

The changes in this PR will be included in the next version bump.

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@pkg-pr-new

pkg-pr-new Bot commented Sep 8, 2026

Copy link
Copy Markdown

Open in StackBlitz

npm i https://pkg.pr.new/@modelcontextprotocol/sdk@2770

commit: cd3ed36

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.

1 participant