SEP-2164: Standardize resource not found error code (-32602)#2164
SEP-2164: Standardize resource not found error code (-32602)#2164
Conversation
5faa2ee to
348d8e7
Compare
348d8e7 to
310784e
Compare
|
related: modelcontextprotocol/python-sdk#1821 |
|
Previous discussion (for reference): #1545. |
yeah I remember this, but didn't realize it was already so inconsistent. Any client has to handle various values anyway to work with real servers out there, so we might as well just trying and get all servers to converge. |
da439aa to
8e938f2
Compare
Maintainer Activity CheckHi @pja-ant! You're assigned to this SEP but there hasn't been any activity from you in 18 days. Please provide an update on:
If you're no longer able to sponsor this SEP, please let us know so we can find another maintainer. This is an automated message from the SEP lifecycle bot. |
0125e6c to
a2ef384
Compare
a2ef384 to
9d8520d
Compare
|
If we accept this, we should add a compliance test for this. I am a bit worried about the breaking change, particularly if SDKs don't have a good way to return values based on MCP version. Do we have a sense of servers that would break? Of course in general i am in favour of unifying this. |
|
Overall this feels like a reasonable surgical change. My broader concern is our error handling across the board is not well defined, and our conformance tests are light. For example, do we think there are consistent implementations across other resources like prompts/tools etc.. Given this is a breaking change should we do a broader audit here before the June spec release to make sure we are rooting out other breaking changes and feel good about our error handling? One case which we'll need to be able to clearly distinguish as we remove Initialize is
|
Do you mean clients? Clients are the ones that interpret the error, so those are the folks where behaviour changes. Here's the thing though: the status quo is that server SDKs are returning all manner of random things:
So unless you client is e.g. only talking to servers built with specific SDKS, it already has to handle potentially 4 different return values. If your client works with TypeScript servers today then you already handle the proposed error code. If you talk to a Python or Kotlin server then you already have to handle random non-standard error codes. |
I can certainly send claude to do some spelunking! |
|
|
||
| ## Abstract | ||
|
|
||
| The current MCP specification [recommends `-32002`](https://modelcontextprotocol.io/specification/draft/server/resources#error-handling) as the error code for resource not found. However, `-32002` falls within the JSON-RPC "server error" range (`-32000` to `-32099`) which is reserved for implementation-defined errors, not protocol-level semantics. Additionally, SDK implementations are inconsistent — only 4 of 6 official SDKs use `-32002`, while the TypeScript SDK uses `-32602` and the Python SDK uses `0`. |
There was a problem hiding this comment.
-32002falls within the JSON-RPC "server error" range (-32000to-32099) which is reserved for implementation-defined errors, not protocol-level semantics.
This appears to be the only real motivation for this other than inconsistent SDK behavior which isn't very compelling to me considering we can just fix the SDKs. But if this is real motivation, than why not change URL_ELICITATION_REQUIRED (-32042) which also falls in this range? We should at least be consistent.
modelcontextprotocol/schema/draft/schema.ts
Line 324 in 2997e03
I think that would break existing code though, so I don't think it's really worth it. We could easily argue that MCP is an "implementation" of JSON-RPC at large, and we could reserve a subset of the range for MCP protocol use. We could retcon this, and reserve (-32000 to -32049 for MCP-protocol-define server errors) and leave -32050 to -32099 for "application" defined errors.
There was a problem hiding this comment.
This also ends up making the error more ambiguous with other errors, so it doesn't appear to provide any functional enhancements. It just has the potential to break existing applications and use cases.
There was a problem hiding this comment.
I agree w/ @halter73 here, and like the idea of reserving -32000 to -32049 for MCP errors. I also think that resource not found is not quite an "invalid param" and is its own error worth having its own code. (e.g. 404 vs. 400 in http)
From the JSON-RPC docs:
The error codes from and including -32768 to -32000 are reserved for pre-defined errors. Any code within this range, but not defined explicitly below is reserved for future use.
That means we need to decide generally for errors whether:
- we will ONLY ever use the codes in the table below
- we pick some OTHER range of codes (e.g. LSP "reserves" -32800 (note: they had a similar issue with some error codes creeping in, and pinning for backcompat: they have
-32002as "server not initialized") - we "reserve"
-32000to-32049(or similar) for MCP errors
| code | message | meaning |
|---|---|---|
| -32700 | Parse error | Invalid JSON was received by the server.An error occurred on the server while parsing the JSON text. |
| -32600 | Invalid Request | The JSON sent is not a valid Request object. |
| -32601 | Method not found | The method does not exist / is not available. |
| -32602 | Invalid params | Invalid method parameter(s). |
| -32603 | Internal error | Internal JSON-RPC error. |
| -32000 to -32099 | Server error | Reserved for implementation-defined server-errors. |
Another framing is what ELSE would we want to put in the -32000 to -32099 range if we didn't put "resource not found" / "elicitation required". It seems pretty reasonable to keep the current recommendation, and keep future errors in that range.
An okay alternative would be to do the LSP approach which is keep the existing rec for backcompat, but reserve a new range and put all new codes in the new range. I don't think breaking this error code is worth it, we do have 4 SDK's following what the spec says.
There was a problem hiding this comment.
To be clear, doing anything is breaking here, including not changing the spec. If we leave it and fix TypeScript and Python then that could break real clients that were relying on TS/Python behavior. They weren't spec compliant, but doesn't change the fact that we'd break them.
Note that tool/call with non-existent tool or prompt/get with non-existent prompt is -32602. Making resources different would lead to inconsistency.
Not against reserving those JSON ranges for other MCP-specific errors, but goal here is to be consistent with existing methods. The fact that resources is using -36002 is clearly just a typo.
There was a problem hiding this comment.
Can we be consistent but also accept -32002 for back-compat?
And wdyt about expanding this to reserving the range? My thought is that if we're bothering to mess with error codes at all, let's save ourselves revisiting this again the next time we need a more specific error code (e.g. the elicitation one)
There was a problem hiding this comment.
I'd be fine with a back compat notice.
And wdyt about expanding this to reserving the range? My thought is that if we're bothering to mess with error codes at all, let's save ourselves revisiting this again the next time we need a more specific error code (e.g. the elicitation one)
I'm all for reserving this, but as a separate PR I think. Expanding scope here I think would need re-vote anyway, so not sure we save time. Hopefully that can just be a PR and not a whole SEP...
9d8520d to
f74ac84
Compare
The SDK previously returned error code 0 for resource-not-found, making it impossible for clients to distinguish this from other errors. Per SEP-2164, servers should return -32602 (Invalid Params) with the uri in the error data field. Adds ResourceNotFoundError subclass of ResourceError so existing code catching ResourceError continues to work. The internal handler converts it to MCPError with INVALID_PARAMS before it reaches the JSON-RPC layer. Spec: modelcontextprotocol/modelcontextprotocol#2164
|
modelcontextprotocol/python-sdk#2344 - Python SDK draft |
f74ac84 to
1a6b583
Compare
This SEP standardizes the error code for resource not found from
-32002to-32602(Invalid Params), aligning with the JSON-RPC specification. Includes the draft spec change.