{"record":{"id":"895e7412a17a98c8","repo":"ultraworkers/claw-code","slug":"mcp-response-for-method-used-unsupported-jsonrpc","errorCode":null,"errorMessage":"MCP response for {method} used unsupported jsonrpc version `{}`","messagePattern":"MCP response for (.+?) used unsupported jsonrpc version `(.+?)`","errorType":"validation","errorClass":"std::io::Error","httpStatus":null,"severity":"error","filePath":"rust/crates/runtime/src/mcp_stdio.rs","lineNumber":1304,"sourceCode":"    }\n\n    pub async fn read_response<T: DeserializeOwned>(&mut self) -> io::Result<JsonRpcResponse<T>> {\n        self.read_jsonrpc_message().await\n    }\n\n    pub async fn request<TParams: Serialize, TResult: DeserializeOwned>(\n        &mut self,\n        id: JsonRpcId,\n        method: impl Into<String>,\n        params: Option<TParams>,\n    ) -> io::Result<JsonRpcResponse<TResult>> {\n        let method = method.into();\n        let request = JsonRpcRequest::new(id.clone(), method.clone(), params);\n        self.send_request(&request).await?;\n        let response = self.read_response().await?;\n\n        if response.jsonrpc != \"2.0\" {\n            return Err(io::Error::new(\n                io::ErrorKind::InvalidData,\n                format!(\n                    \"MCP response for {method} used unsupported jsonrpc version `{}`\",\n                    response.jsonrpc\n                ),\n            ));\n        }\n\n        if response.id != id {\n            return Err(io::Error::new(\n                io::ErrorKind::InvalidData,\n                format!(\n                    \"MCP response for {method} used mismatched id: expected {id:?}, got {:?}\",\n                    response.id\n                ),\n            ));\n        }\n","sourceCodeStart":1286,"sourceCodeEnd":1322,"githubUrl":"https://github.com/ultraworkers/claw-code/blob/08106b0c3771ef5b4a5aa176acccd460e88b7325/rust/crates/runtime/src/mcp_stdio.rs#L1286-L1322","documentation":"`McpStdioProcess::request` (runtime/src/mcp_stdio.rs:1304) validates every JSON-RPC response from the spawned MCP server: `response.jsonrpc` must equal \"2.0\" exactly. claw always sends \"2.0\" on requests; a server replying with \"1.0\", \"2\", or any other string gets `InvalidData`. Note `jsonrpc` is a required String field on JsonRpcResponse — a response OMITTING it fails serde deserialization earlier, so this error specifically means a wrong explicit value.","triggerScenarios":"A homegrown MCP server echoing JSON-RPC 1.0 style responses (\"jsonrpc\":\"1.0\" or version pulled from config); a server deriving the field from the negotiated protocolVersion of initialize; hardcoded \"2\" without the patch component.","commonSituations":"Adapting an old JSON-RPC 1.0 service as an MCP server; typos in hand-serialized responses; forks that renamed the constant.","solutions":["In the server, always serialize responses with \"jsonrpc\":\"2.0\" (use the SDK's response type, not hand-built JSON).","Check the exact value in the error message against the server's serialization code.","If using an SDK, upgrade it — old JSON-RPC 1.0 libraries do not emit the field correctly."],"exampleFix":"// before (server)\n{\"id\":1,\"result\":{}}                                  // no/invalid version -> deserialize fail or this error\n\n// after (server)\n{\"jsonrpc\":\"2.0\",\"id\":1,\"result\":{}}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"match process.request(id, method, params).await {\n    Err(e) if e.kind() == io::ErrorKind::InvalidData\n        && e.to_string().contains(\"unsupported jsonrpc version\") => {\n        // peer is not spec-compliant: log the version it sent and drop the server\n    }\n    other => other,\n}","preventionTips":["Always serialize responses with \"jsonrpc\":\"2.0\"; use an SDK response type","A response with NO jsonrpc field fails deserialization before this check — include it","Assert the field in your server's response unit tests"],"tags":["mcp","jsonrpc","protocol-version"],"backgroundTag":"jsonrpc-version-mismatch","analyzedSha":"08106b0c3771ef5b4a5aa176acccd460e88b7325","analyzedAt":"2026-08-18T00:29:38.590Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}