Standardize Resource Not Found Errors on -32602 with URI Data per SEP-2164#402
Merged
koic merged 1 commit intoJun 14, 2026
Merged
Conversation
…-2164 ## Motivation and Context SEP-2164 (modelcontextprotocol/modelcontextprotocol#2164, merged for the 2026-07-28 spec release) standardizes the resource-not-found error on the JSON-RPC Invalid Params code (-32602), dropping the legacy -32002 code, and both reference SDK implementations attach the requested URI as structured error data (typescript-sdk#2267 throws `InvalidParams` with `data: { uri }`; python-sdk#2344 adds a `ResourceNotFoundError` that maps to `code=-32602, data={"uri": ...}`). The Ruby server already used -32602 (via `error_type: :invalid_params`) for its built-in not-found path (`completion/complete` with an unknown `ref/resource` URI), but the response carried no structured data and the generic "Invalid params" message, and there was no public error class for `resources_read_handler` blocks to raise. The Ruby client never special-cased -32002, so nothing needed removal there. - New public `MCP::Server::ResourceNotFoundError` (modeled on the `URLElicitationRequiredError` precedent): code -32602, message `"Resource not found: <uri>"`, and `data: { uri: <uri> }`. Custom `resources_read_handler` blocks raise it for unknown URIs; the README documents the pattern. - The `completion/complete` `ref/resource` not-found path now raises this class, so its error response gains `data: { uri: }` and a descriptive message instead of the generic "Invalid params" text. - The default `resources/read` behavior (returning empty contents for unknown URIs when no handler is registered) is intentionally unchanged; raising there would alter existing wire behavior. Resolves modelcontextprotocol#379. ## How Has This Been Tested? New tests in `test/mcp/server_test.rb`: - `resources/read` with a handler raising `ResourceNotFoundError` responds with code -32602, message `"Resource not found: file:///missing.txt"`, and `data: { uri: "file:///missing.txt" }` - `completion/complete` with an unknown `ref/resource` URI carries the same code, message, and structured data New test in `test/mcp/client_test.rb` asserts `Client#read_resource` surfaces the -32602 code and the `data` hash unmodified through `Client::ServerError` (regression: no special-casing swallows it). The pre-existing completion error-code tests pass unchanged. `bundle exec rake` (tests, RuboCop, and conformance baseline) passes. ## Breaking Changes None at the JSON-RPC code level (-32602 before and after). The `completion/complete` resource-not-found error response changes shape within the error object: `message` becomes `"Resource not found: <uri>"` instead of `"Invalid params"`, and `data` becomes `{ uri: <uri> }` instead of the message string. Both members are advisory per JSON-RPC 2.0.
atesgoral
approved these changes
Jun 13, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Motivation and Context
SEP-2164 (modelcontextprotocol/modelcontextprotocol#2164, merged for the 2026-07-28 spec release) standardizes the resource-not-found error on the JSON-RPC Invalid Params code (-32602), dropping the legacy -32002 code, and both reference SDK implementations attach the requested URI as structured error data (typescript-sdk#2267 throws
InvalidParamswithdata: { uri }; python-sdk#2344 adds aResourceNotFoundErrorthat maps tocode=-32602, data={"uri": ...}).The Ruby server already used -32602 (via
error_type: :invalid_params) for its built-in not-found path (completion/completewith an unknownref/resourceURI), but the response carried no structured data and the generic "Invalid params" message, and there was no public error class forresources_read_handlerblocks to raise. The Ruby client never special-cased -32002, so nothing needed removal there.MCP::Server::ResourceNotFoundError(modeled on theURLElicitationRequiredErrorprecedent): code -32602, message"Resource not found: <uri>", anddata: { uri: <uri> }. Customresources_read_handlerblocks raise it for unknown URIs; the README documents the pattern.completion/completeref/resourcenot-found path now raises this class, so its error response gainsdata: { uri: }and a descriptive message instead of the generic "Invalid params" text.resources/readbehavior (returning empty contents for unknown URIs when no handler is registered) is intentionally unchanged; raising there would alter existing wire behavior.Resolves #379.
How Has This Been Tested?
New tests in
test/mcp/server_test.rb:resources/readwith a handler raisingResourceNotFoundErrorresponds with code -32602, message"Resource not found: file:///missing.txt", anddata: { uri: "file:///missing.txt" }completion/completewith an unknownref/resourceURI carries the same code, message, and structured dataNew test in
test/mcp/client_test.rbassertsClient#read_resourcesurfaces the -32602 code and thedatahash unmodified throughClient::ServerError(regression: no special-casing swallows it).The pre-existing completion error-code tests pass unchanged.
bundle exec rake(tests, RuboCop, and conformance baseline) passes.Breaking Changes
None at the JSON-RPC code level (-32602 before and after). The
completion/completeresource-not-found error response changes shape within the error object:messagebecomes"Resource not found: <uri>"instead of"Invalid params", anddatabecomes{ uri: <uri> }instead of the message string. Both members are advisory per JSON-RPC 2.0.Types of changes
Checklist