Skip to content

Fix: return protocol errors for invalid arguments and server errors#285

Merged
koic merged 1 commit intomodelcontextprotocol:mainfrom
sqrlington:fix/revert-error-handling-to-protocol-errors
Apr 1, 2026
Merged

Fix: return protocol errors for invalid arguments and server errors#285
koic merged 1 commit intomodelcontextprotocol:mainfrom
sqrlington:fix/revert-error-handling-to-protocol-errors

Conversation

@sqrlington
Copy link
Copy Markdown
Contributor

@sqrlington sqrlington commented Apr 1, 2026

Motivation and Context

PR #231 fixed unknown tool calls to return protocol errors per the MCP spec, but two of the three protocol error cases still return isError: true instead of JSON-RPC errors:

  • Invalid arguments — missing required arguments and schema validation failures return isError: true instead of -32602
  • Server errors — uncaught exceptions during tool execution return isError: true instead of -32603

Per the MCP spec, these are protocol errors, not tool execution errors.

Fixes #284.

How Has This Been Tested?

Updated existing tests to assert JSON-RPC error responses instead of isError: true results. All tests pass, rubocop clean.

Breaking Changes

Clients relying on isError: true for invalid arguments or server errors will now receive JSON-RPC error responses instead. This matches the behavior PR #231 introduced for unknown tools.

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


result
rescue => e
report_exception(e, { request: request })
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

call_tool no longer calls report_exception before re-raising. The rescue here now receives RequestHandlerError instead of the original exception, so exception_reporter loses the original
class and backtrace.

--- a/lib/mcp/server.rb
+++ b/lib/mcp/server.rb
@@ -317,7 +317,8 @@ module MCP

           result
         rescue => e
-          report_exception(e, { request: request })
+          reported = e.is_a?(RequestHandlerError) ? (e.original_error || e) : e
+          report_exception(reported, { request: request })
           if e.is_a?(RequestHandlerError)
             add_instrumentation_data(error: e.error_type)
             raise e

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Took the liberty of refactoring the rescue block to avoid the duplicated is_a? checks when I implemented this suggestion

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, great! Thanks!

Per the MCP spec, invalid arguments and server errors are protocol
errors (JSON-RPC error responses), not tool execution errors
(isError: true). PR modelcontextprotocol#165 moved all error cases to isError: true,
and PR modelcontextprotocol#231 only restored protocol errors for unknown tools.

This fixes the remaining two cases: invalid arguments (-32602) and
server errors (-32603).

Ref: https://modelcontextprotocol.io/specification/2024-11-05/server/tools#error-handling
@sqrlington sqrlington force-pushed the fix/revert-error-handling-to-protocol-errors branch from 81da497 to 8dd0379 Compare April 1, 2026 18:24
@sqrlington sqrlington requested a review from koic April 1, 2026 18:26
@koic koic merged commit 6669601 into modelcontextprotocol:main Apr 1, 2026
11 checks passed
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.

Protocol errors still returned as tool execution errors (invalid arguments, server errors)

2 participants