mcp: a handler error without a code reaches the peer as JSON-RPC error code 0
メンテナーはふだん 1 日以内に返信
まだ誰も着手していません。
評価
- 難易度
- 4/5
- 見積もり時間
- 3〜5日
- 初心者へのやさしさ
- 35/100
- issue の種類
- バグ
- 明瞭さ
- 明確に書かれている
- 活発さ
- 活発
- 技術スタック
- go
調査の方向性
Start with internal/jsonrpc2/messages.go and toWireError, then read #1367 and #1393 for the related behavior. Compare the proposed default in toWireError with handling errors at MCP call sites, including the duplicate initialize case. Done means uncoded handler errors reach peers as -32603, duplicate initialize as -32600, existing coded errors retain their codes, and the agreed MCPGODEBUG option and 1.9.0 documentation are addressed.
索引モデルが issue の本文から書いたものです。
説明
What happens
When a handler returns an ordinary Go error, the peer receives it with "code": 0. Measured on main at b5d319b:
| side | where the plain error comes from | response |
|---|---|---|
| server | prompts/get handler |
{"code":0,"message":"prompt boom"} |
| server | resources/read handler (resource) |
{"code":0,"message":"resource boom"} |
| server | resources/read handler (template) |
{"code":0,"message":"template boom"} |
| server | tools/call, raw ToolHandler from Server.AddTool |
{"code":0,"message":"raw boom"} |
| server | CompletionHandler |
{"code":0,"message":"complete boom"} |
| server | SubscribeHandler / UnsubscribeHandler |
{"code":0,"message":"subscribe boom"} |
| server | receiving middleware | {"code":0,"message":"middleware boom"} |
| server | handler added with AddReceivingCustomMethod |
{"code":0,"message":"custom boom"} |
| server | second initialize on a legacy session (SDK's own error) |
{"code":0,"message":"duplicate \"initialize\" received"} |
| client | CreateMessageHandler |
{"code":0,"message":"sampling boom"} |
| client | ElicitationHandler |
{"code":0,"message":"elicit boom"} |
| client | receiving middleware | {"code":0,"message":"client middleware boom"} |
The server rows give the same answer over IOTransport on 2025-11-25, over IOTransport on 2026-07-28, and over stateless Streamable HTTP on 2026-07-28 (subscribe/unsubscribe and the second initialize on 2025-11-25 only). The client rows were run on 2025-11-25 over IOTransport. context.DeadlineExceeded returned from a handler is answered the same way.
Not affected:
- A handler that returns a
*jsonrpc.Error, or an error wrapping one, keeps its code. ResourceNotFoundErroris answered with-32602.- A typed
ToolHandlerFor: its error becomes anisErrorresult.
Why
Same cause as #1367. toWireError in internal/jsonrpc2/messages.go copies a code only from an error that is or wraps a WireError, so a plain error keeps the zero value. #1393 fixed the one site that issue was about.
What the specification says
- Prompts, Error Handling (2025-11-25 and 2026-07-28): "Internal errors:
-32603(Internal error)". - Resources, 2026-07-28: "Servers SHOULD return
-32603for internal errors." 2025-11-25 lists "Internal errors:-32603". - Tools, Error Handling: protocol errors are "standard JSON-RPC errors for issues like … Server errors".
For comparison, the TypeScript SDK (1.32.1, shared/protocol.js) answers with -32603 when a handler throws an error that has no integer code.
Proposal
Answer with -32603 (jsonrpc.CodeInternalError) when an error that carries no code is about to be sent, keeping the message as it is. For the duplicate initialize, -32600, matching #1393.
Two ways to do it, and I would like your preference before writing the patch:
- In
toWireError: default to-32603whenever no code is set. One change, covers every row above and future sites, but changes every such answer at once. - At the call sites in
mcponly. Leaves the jsonrpc2 default alone, but it is a dozen sites today and each new handler type needs the same care.
Given how many sites there are, I lean towards 1. Either way gated behind an MCPGODEBUG option and documented under 1.9.0, as in #1393. I can send the PR for whichever you choose.
The only test I found that expects 0 is internal/jsonrpc2/wire_test.go, which builds the error with code 0 explicitly, so it would not change.
AI disclosure: investigated and drafted with Claude Code; I reproduced and reviewed it.
- 主要言語
- Go
- スター
- 5.2k
- フォーク
- 583
- 平均マージ
- 1日 8時間
- マージ済み PR(30日)
- 50
環境構築
このプロジェクトの開発コンテナを、あなたの GitHub アカウントでブラウザ上に起動します。
- Dockerfile・Docker Compose ファイルなし
- プルリクエストのテンプレートあり
- コントリビューションガイドを読む
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
modelcontextprotocol/go-sdk のほかの issue
-
auth: resource metadata lookup accepts URLs from non-Bearer challenges対応中かも @jay23606 が 1 日前に担当しました。 オープン
難易度 2/5 1〜3時間 初心者へのやさしさ 82/100
modelcontextprotocol/go-sdk#1379 ·
メンテナーはふだん 1 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 76/100
modelcontextprotocol/go-sdk#1372 ·
メンテナーはふだん 1 日以内に返信
-
Session-lifecycle bookkeeping logs at info, spamming multiple log lines per request on stateless streamable HTTP対応中かも @anneheartrecord が 47 日前に担当しました。 オープンP3
難易度 2/5 1〜3時間 初心者へのやさしさ 75/100
modelcontextprotocol/go-sdk#1204 · リアクション 1 件 ·
メンテナーはふだん 1 日以内に返信
-
Expose generic `SendNotification` on `ServerSession` for custom protocol extensions対応中かも @ajuijas が 212 日前に担当しました。 オープンneeds investigation
難易度 2/5 1〜3時間 初心者へのやさしさ 72/100
modelcontextprotocol/go-sdk#745 · コメント 13 件 · リアクション 1 件 ·
メンテナーはふだん 1 日以内に返信
-
mcp: rejected request IDs receive no JSON-RPC error envelope対応中かも @skosovsky が 1 日前に担当しました。 オープン
難易度 4/5 1〜2日 初心者へのやさしさ 68/100
modelcontextprotocol/go-sdk#1391 ·
メンテナーはふだん 1 日以内に返信
modelcontextprotocol/go-sdk の issue をすべて見る
似ている issue
-
TOTP enrollment returns 500 for phone-only users (empty TOTP account name)対応中かも @emiliosandoval4 が今日担当しました。 オープン
難易度 2/5 1〜3時間 初心者へのやさしさ 60/100
メンテナーはふだん 1 日以内に返信
-
8.9 to 8.10 Helm upgrade guide still says deprecated keys are removed in chart v16 (Camunda 8.11)オープン
難易度 1/5 1時間未満 初心者へのやさしさ 78/100
camunda/camunda-platform-helm#7559 ·
メンテナーはふだん 1 日以内に返信
-
triage/pending-triage
難易度 2/5 1〜3時間 初心者へのやさしさ 74/100
external-secrets/external-secrets#7117 ·
メンテナーはふだん 2 日以内に返信
-
bug
難易度 2/5 1〜3時間 初心者へのやさしさ 72/100
ENTERPILOT/GoModel#1183 · コメント 1 件 ·
メンテナーはふだん 1 日以内に返信
-
createEtcdKV fails on a single transient etcd endpoint sync timeout対応中かも @vldmit が今日担当しました。 オープンcontribution
難易度 2/5 1〜3時間 初心者へのやさしさ 70/100
メンテナーはふだん 1 日以内に返信