Malformed params on spec request methods return -32603 Internal error instead of -32602 Invalid params
Maintainers usually reply within 1 day
Assessment
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Newbie friendliness
- 78/100
- Issue type
- Bug
- Clarity
- Clearly specified
- Activity status
- Active
- Tech stack
- typescript
- Domain
- api, backend-api-design
Research direction
Inspect the two-argument branch of Protocol.setRequestHandler in the dist/src-*.mjs files around lines 6842–6845 for versions 2.1.0 and 2.2.0. Use the @mcpjam/sdk conformance probe or equivalent malformed requests for prompts/get and logging/setLevel, with well-formed controls, and verify invalid wire parameters return -32602 without running the handler while tools/call remains correct.
Written by the indexing model from the issue text.
Description
Summary
A request whose params fail wire-schema validation is answered with -32603 (Internal error) and the raw validation issues as the message, for every spec method registered through the two-argument setRequestHandler(method, handler). JSON-RPC 2.0 and the MCP spec define this case as -32602 (Invalid params).
tools/call is already correct (Invalid tools/call request: …, -32602), as is the three-argument setRequestHandler(method, { params }, handler) path (Invalid params for <method>), so the inconsistency is only on the generic two-argument path.
Reproduction
Any server on @modelcontextprotocol/server 2.1.0 or 2.2.0 (latest at time of writing) that registers spec handlers with the two-argument form:
POST /mcp {"jsonrpc":"2.0","id":1,"method":"prompts/get","params":{}}
→ {"error":{"code":-32603,"message":"[ { \"expected\": \"string\", \"code\": \"invalid_type\", ..."}}
POST /mcp {"jsonrpc":"2.0","id":2,"method":"logging/setLevel","params":{"level":"loud"}}
→ {"error":{"code":-32603,"message":"[ { \"code\": \"invalid_value\", ..."}}
POST /mcp {"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":123}}
→ {"error":{"code":-32602,"message":"Invalid tools/call request: ..."}} (correct)
Each probe was paired with a well-formed control on the same method (e.g. logging/setLevel with "info"), which succeeds, so the method itself is served.
Cause
In Protocol.setRequestHandler, two-argument branch (dist src-*.mjs, around line 6842 in 2.1.0 and 6845 in 2.2.0):
if (!outcome.ok) {
if (outcome.reason === "not-in-era") throw new ProtocolError(ProtocolErrorCode.InternalError, `No wire schema for ${method} in the resolved era`);
throw new Error(outcome.message); // ← a plain Error, reported as -32603
}
Suggested fix
throw new ProtocolError(ProtocolErrorCode.InvalidParams, `Invalid params for ${method}: ${outcome.message}`);
This matches the tools/call and three-argument paths. The handler never runs for these requests, so a server cannot correct the code itself without re-registering every spec method on the three-argument path (which bypasses the era-aware codec).
Found by an automated conformance probe built on @mcpjam/sdk, with a well-formed control per method.
- Dominant language
- TypeScript
- Stars
- 13.5k
- Forks
- 2.3k
- Avg merge
- 2d 4h
- Merged PRs (30d)
- 45
Getting set up
- No Dockerfile or Docker Compose file
- No pull request template
- Read the contributing guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from modelcontextprotocol/typescript-sdk
-
v1 v2
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
modelcontextprotocol/typescript-sdk#2946 ·
Maintainers usually reply within 1 day
-
[v2] URI template reserved expansions encode existing %HH sequences againPossibly taken @takagibit18 claimed this 2 days ago. Openv1 v2
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
modelcontextprotocol/typescript-sdk#2920 · 1 comment ·
Maintainers usually reply within 1 day
-
[v2] URI template strict expansions leave !'()* unencodedPossibly taken @takagibit18 claimed this 2 days ago. Openv1 v2
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
modelcontextprotocol/typescript-sdk#2919 · 1 comment ·
Maintainers usually reply within 1 day
-
Unconditional `prompt=consent` (when `offline_access` in scope) blocks OAuth in Entra tenants with user consent disabled + admin consent grantedPossibly taken @dasjideepak claimed this 9 days ago. Openv1 v2
Difficulty 1/5 Under an hour Newbie friendliness 90/100
modelcontextprotocol/typescript-sdk#2867 · 1 comment ·
Maintainers usually reply within 1 day
-
v1 v2
Difficulty 2/5 1-3 hours Newbie friendliness 70/100
modelcontextprotocol/typescript-sdk#2854 · 1 comment ·
Maintainers usually reply within 1 day
All issues in modelcontextprotocol/typescript-sdk
Similar issues
-
Difficulty 2/5 1-3 hours Newbie friendliness 67/100
ehmpathy/rhachet-roles-bhrain#586 ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 65/100
OHDSI/Data2Evidence#3496 ·
Maintainers usually reply within 2 days
-
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
apache/rocketmq-dashboard#5594 ·
Maintainers usually reply within 3 days
-
react-doctor severity:warning tech-debt
Difficulty 1/5 Under an hour Newbie friendliness 88/100
digidem/comapeo-cloud-app#418 ·
Maintainers usually reply within 1 day