Skip to content

Standardize Resource Not Found Errors on -32602 with URI Data per SEP-2164#402

Merged
koic merged 1 commit into
modelcontextprotocol:mainfrom
koic:resource_not_found_error_data
Jun 14, 2026
Merged

Standardize Resource Not Found Errors on -32602 with URI Data per SEP-2164#402
koic merged 1 commit into
modelcontextprotocol:mainfrom
koic:resource_not_found_error_data

Conversation

@koic

@koic koic commented Jun 13, 2026

Copy link
Copy Markdown
Member

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 #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.

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation update

Checklist

  • I have read the MCP Documentation
  • My code follows the repository's style guidelines
  • New and existing tests pass locally
  • I have added appropriate error handling
  • I have added or updated documentation as needed

…-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.
@koic koic merged commit 783eb63 into modelcontextprotocol:main Jun 14, 2026
11 checks passed
@koic koic deleted the resource_not_found_error_data branch June 14, 2026 07:52
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.

SEP-2164: Standardize resource not found error code (-32602)

2 participants