Skip to content

mcp: bind peer cancellation before request ID reuse - #1390

Merged
guglielmo-san merged 3 commits into
modelcontextprotocol:mainfrom
skosovsky:fix/cancellation-request-id-reuse
Oct 13, 2026
Merged

guglielmo-san merged 3 commits into
modelcontextprotocol:mainfrom
skosovsky:fix/cancellation-request-id-reuse

Conversation

@skosovsky

@skosovsky skosovsky commented Oct 12, 2026 •

Copy link
Copy Markdown
Contributor

A peer cancellation is currently scheduled in a goroutine before looking up its request. If the old invocation finishes and the read loop admits a replacement with the same ID first, that lookup can cancel the replacement.

Call CancelCause directly from canceller.Preempt, binding cancellation to the active invocation before the read loop advances. CancelCause captures the request under the existing connection lock and cancels its context; it does not wait for handler completion or response delivery. The peer's cancellation reason is preserved. No public API, numeric-ID behavior, or response-suppression behavior changes.

This PR changes only mcp/transport.go. The dedicated cancellation-reuse test harness is retained downstream.

Validation on Go 1.27.1, darwin/arm64:

  • After removing the dedicated test: go test -race ./mcp -run TestCancellation -count=1 -timeout=180s and git diff --check passed.
  • The unchanged production fix previously passed go test ./... -timeout=10m, cancellation race tests, go vet ./..., and go build ./....
  • Separate protocol conformance scripts were not run.

Related: #1267 changes this same call to CancelFromPeer; if that lands first, the invocation lookup should still happen before returning from preemption. This fix is independent of #1375 and contains no numeric decoding or transport hardening changes.

Fixes #1389.

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 12, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-12T14:40:17.560937Z f5811a6 PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

Comment thread mcp/cancellation_reuse_test.go Outdated
Comment on lines +1 to +6
// Copyright 2026 The Go MCP SDK Authors. All rights reserved.
// Use of this source code is governed by the license
// that can be found in the LICENSE file.

package mcp

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

considering that this error is very niche, can you please discard this test and just leave the code change?

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.

Done — removed cancellation_reuse_test.go from this PR and kept only the production change in mcp/transport.go. The additional regression harness remains in our downstream integration branch. Existing cancellation tests pass with -race after the removal.

@guglielmo-san
guglielmo-san merged commit 7cdd99f into modelcontextprotocol:main Oct 13, 2026
9 checks passed
@guglielmo-san

Copy link
Copy Markdown
Contributor

@skosovsky thank you for the contribution!

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.

mcp: deferred cancellation can target a new invocation reusing the request ID

2 participants