You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Malformed params on spec request methods return -32603 Internal error instead of -32602 Invalid params #2916
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")thrownewProtocolError(ProtocolErrorCode.InternalError,`No wire schema for ${method} in the resolved era`);thrownewError(outcome.message);// ← a plain Error, reported as -32603}
Suggested fix
thrownewProtocolError(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.
I reproduced it on @modelcontextprotocol/server 2.2.0: prompts/get with empty params returns -32603 with the raw validation message, while tools/call returns -32602 as expected.
Plan: in the two-argument branch of Protocol.setRequestHandler, throw ProtocolError(ProtocolErrorCode.InvalidParams, ...) for validation failures, the same way the three-argument path does. I'll leave the "not-in-era" branch as it is. I'll add regression tests for prompts/get and logging/setLevel.
@anthonychung , were you planning to send a PR for this yourself? If not, could a maintainer assign it to me? Also, since it's labelled both v1 and v2, should I target main or v1.x?
Quick update on this one. Before opening a PR for main, I found that #2492 already makes the same fix there: it throws ProtocolError(InvalidParams, …) in the two-argument setRequestHandler branch and updates the corpus fixture and e2e knownFailures. It also still merges cleanly, so I won't open a duplicate. A review of #2492 should close this for main.
v1.x has the same bug, and it's a bit worse there. Protocol.setRequestHandler lets the raw ZodError escape, so even tools/call with {"name":123} comes back as -32603, and the client and server InvalidParams checks never run. I opened #2932 as the v1.x fix. It returns -32602 with a readable message, adds a regression test for prompts/get and logging/setLevel, and removes the three e2e knownFailures that recorded the old behaviour.
Happy to make any changes needed on either.
Hi maintainers, thanks for the updates. I see that #2492 covers main and #2932 covers v1.x.
Is there any remaining work on this issue where another contributor could help, such as additional regression coverage or Windows validation? I develop on Windows 10 without WSL and would appreciate confirmation of a suitable scope before starting.
I’m looking for funded contribution opportunities. Is any remaining work here eligible for a bounty or sponsorship? If so, could you clarify the amount, acceptance conditions, payment method and timing, and eligibility for a contributor based in Nigeria? If this is volunteer-only work, please confirm.
If both PRs fully cover the issue, I understand. Thank you.
Activity
Gauravtiwari31 commentedon Oct 2, 2026
Hi, I'd like to take this one.
I reproduced it on @modelcontextprotocol/server 2.2.0: prompts/get with empty params returns -32603 with the raw validation message, while tools/call returns -32602 as expected.
Plan: in the two-argument branch of Protocol.setRequestHandler, throw ProtocolError(ProtocolErrorCode.InvalidParams, ...) for validation failures, the same way the three-argument path does. I'll leave the "not-in-era" branch as it is. I'll add regression tests for prompts/get and logging/setLevel.
@anthonychung , were you planning to send a PR for this yourself? If not, could a maintainer assign it to me? Also, since it's labelled both v1 and v2, should I target main or v1.x?
Gauravtiwari31 commentedon Oct 2, 2026
Quick update on this one. Before opening a PR for main, I found that #2492 already makes the same fix there: it throws ProtocolError(InvalidParams, …) in the two-argument setRequestHandler branch and updates the corpus fixture and e2e knownFailures. It also still merges cleanly, so I won't open a duplicate. A review of #2492 should close this for main.
v1.x has the same bug, and it's a bit worse there. Protocol.setRequestHandler lets the raw ZodError escape, so even tools/call with {"name":123} comes back as -32603, and the client and server InvalidParams checks never run. I opened #2932 as the v1.x fix. It returns -32602 with a readable message, adds a regression test for prompts/get and logging/setLevel, and removes the three e2e knownFailures that recorded the old behaviour.
Happy to make any changes needed on either.
penielgold-hub commentedon Oct 4, 2026
Hi maintainers, thanks for the updates. I see that #2492 covers main and #2932 covers v1.x.
Is there any remaining work on this issue where another contributor could help, such as additional regression coverage or Windows validation? I develop on Windows 10 without WSL and would appreciate confirmation of a suitable scope before starting.
I’m looking for funded contribution opportunities. Is any remaining work here eligible for a bounty or sponsorship? If so, could you clarify the amount, acceptance conditions, payment method and timing, and eligibility for a contributor based in Nigeria? If this is volunteer-only work, please confirm.
If both PRs fully cover the issue, I understand. Thank you.