Skip to content

fix(dispatcher): advance mint counter past caller-supplied IDs (#3126) - #3274

Open
elang2 wants to merge 3 commits into
modelcontextprotocol:mainfrom
elang2:fix/dispatcher-id-collision
Open

fix(dispatcher): advance mint counter past caller-supplied IDs (#3126)#3274
elang2 wants to merge 3 commits into
modelcontextprotocol:mainfrom
elang2:fix/dispatcher-id-collision

Conversation

@elang2

@elang2 elang2 commented Aug 9, 2026

Copy link
Copy Markdown

Summary

When a caller supplies an integer request ID, the dispatcher's internal _next_id counter can mint the same value for a later request. The spec says IDs MUST NOT be reused within a session, so this is a correctness bug.

The fix eagerly advances _next_id to max(_next_id, supplied_id) in both JsonRpcDispatcher and DirectDispatcher. Two lines per dispatcher, no behavioral change for callers using string-only IDs.

Test plan

  • 4 new regression tests (2 per dispatcher via pair_factory parametrization)
  • All 894 tests pass
  • Covers both in-flight and completed caller-supplied ID scenarios

Fixes #3126

elang2 added 3 commits August 2, 2026 16:44
…ontextprotocol#3126)

When a caller supplies an integer request ID via CallOptions["request_id"],
advance the monotonic mint counter past it so future auto-minted IDs never
collide with a previously-used supplied ID. This satisfies the JSON-RPC spec
requirement that request IDs MUST NOT be reused within the same session.

Applied to both JSONRPCDispatcher and DirectDispatcher.
Add a test that exercises the while-loop body in
DirectDispatcher._dispatch_request which skips past in-flight IDs
when minting. CI was failing with 99.99% coverage (fail-under=100%)
because line 264 was unreachable through normal API usage — the
max() advancement on caller-supplied IDs prevents natural collisions.
The test injects synthetic in-flight keys to prove the guard works.
The test accesses DirectDispatcher internals (_in_flight_ids, _next_id)
but direct_pair() returns the Dispatcher protocol. Add an isinstance
assertion so pyright can see the concrete type.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

No issues found across 3 files

Re-trigger cubic

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.

Dispatcher mints a request id already used by a completed caller-supplied request (spec: ids MUST NOT be reused in a session)

1 participant