Skip to content

fix(transport): validate JSON-RPC request ID is a safe integer#1809

Open
Aboudjem wants to merge 3 commits intomodelcontextprotocol:mainfrom
Aboudjem:fix/validate-safe-integer-request-id
Open

fix(transport): validate JSON-RPC request ID is a safe integer#1809
Aboudjem wants to merge 3 commits intomodelcontextprotocol:mainfrom
Aboudjem:fix/validate-safe-integer-request-id

Conversation

@Aboudjem
Copy link
Copy Markdown

Summary

Fixes #1765 - Server hangs indefinitely when JSON-RPC request ID exceeds Number.MAX_SAFE_INTEGER.

Root cause: When a request arrives with a numeric ID like 9007199254740992 (MAX_SAFE_INTEGER + 1), Zod v4's z.number().int() correctly rejects it (.int() enforces the safe integer range). However, the rejected message falls through to the else branch in the onmessage handler, which calls _onerror with "Unknown message type" and silently drops the message without ever sending a response. The client waits forever for a response that never comes.

Fix: In the onmessage handler within Protocol.connect(), detect request-like messages that fail schema validation (have jsonrpc, id, and method fields but didn't pass isJSONRPCRequest) and respond with a JSON-RPC -32600 (Invalid Request) error instead of silently dropping them.

Changes

  • packages/core/src/shared/protocol.ts - Added validation in the onmessage handler to detect and respond to malformed request messages
  • packages/core/test/shared/protocol.test.ts - Added 3 tests: unsafe integer ID returns error, MAX_SAFE_INTEGER works normally, string IDs work normally

Test plan

  • New test: request with ID exceeding MAX_SAFE_INTEGER receives InvalidRequest error response
  • New test: request with ID at exactly MAX_SAFE_INTEGER is processed normally
  • New test: request with string ID (even large numeric string) is processed normally
  • All 443 existing core tests continue to pass

@Aboudjem Aboudjem requested a review from a team as a code owner March 29, 2026 00:20
@changeset-bot
Copy link
Copy Markdown

changeset-bot bot commented Mar 29, 2026

🦋 Changeset detected

Latest commit: 0a62c4c

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

This PR includes changesets to release 1 package
Name Type
@modelcontextprotocol/core Patch

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
Copy link
Copy Markdown

pkg-pr-new bot commented Mar 29, 2026

Open in StackBlitz

@modelcontextprotocol/client

npm i https://pkg.pr.new/modelcontextprotocol/typescript-sdk/@modelcontextprotocol/client@1809

@modelcontextprotocol/server

npm i https://pkg.pr.new/modelcontextprotocol/typescript-sdk/@modelcontextprotocol/server@1809

@modelcontextprotocol/express

npm i https://pkg.pr.new/modelcontextprotocol/typescript-sdk/@modelcontextprotocol/express@1809

@modelcontextprotocol/hono

npm i https://pkg.pr.new/modelcontextprotocol/typescript-sdk/@modelcontextprotocol/hono@1809

@modelcontextprotocol/node

npm i https://pkg.pr.new/modelcontextprotocol/typescript-sdk/@modelcontextprotocol/node@1809

commit: 0a62c4c

Aboudjem and others added 2 commits March 30, 2026 00:05
When a JSON-RPC request arrives with a numeric ID exceeding
Number.MAX_SAFE_INTEGER, Zod schema validation correctly rejects it
(z.number().int() enforces safe integer range in Zod v4). However, the
rejected message falls through to the "Unknown message type" error
handler, which silently drops it without sending any response back to
the client. This causes the server to appear permanently hung.

This fix detects request-like messages that fail schema validation in
the onmessage handler and responds with a JSON-RPC -32600 (Invalid
Request) error instead of silently ignoring them.

Closes modelcontextprotocol#1765

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
tsgo flags `mock.calls[0][0]` as "Object is possibly undefined" — add
`!` after the first index access to match the convention used everywhere
else in this test file.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@Aboudjem Aboudjem force-pushed the fix/validate-safe-integer-request-id branch from 17f6f8c to d18ce5f Compare March 29, 2026 22:09
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
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.

Server hangs indefinitely when JSON-RPC request ID exceeds

1 participant