{"record":{"id":"9c23b778f6e17524","repo":"can1357/oh-my-pi","slug":"malformed-json-rpc-error-response","errorCode":null,"errorMessage":"Malformed JSON-RPC error response","messagePattern":"Malformed JSON-RPC error response","errorType":"exception","errorClass":"SyntaxError","httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/mcp/transports/http.ts","lineNumber":511,"sourceCode":"\n\t\t\t// Handle SSE response\n\t\t\tif (contentType.includes(\"text/event-stream\")) {\n\t\t\t\treturn this.#parseSSEResponse<T>(response, id, options);\n\t\t\t}\n\n\t\t\tstage = \"decode\";\n\t\t\t// Handle JSON response\n\t\t\tconst result: unknown = await response.json();\n\t\t\tif (!isRecord(result) || result.jsonrpc !== \"2.0\" || (!(\"result\" in result) && !(\"error\" in result))) {\n\t\t\t\tthrow new SyntaxError(\"Malformed JSON-RPC response\");\n\t\t\t}\n\t\t\tif (result.error !== undefined) {\n\t\t\t\tif (\n\t\t\t\t\t!isRecord(result.error) ||\n\t\t\t\t\ttypeof result.error.code !== \"number\" ||\n\t\t\t\t\ttypeof result.error.message !== \"string\"\n\t\t\t\t) {\n\t\t\t\t\tthrow new SyntaxError(\"Malformed JSON-RPC error response\");\n\t\t\t\t}\n\t\t\t\tthrow createMCPJsonRpcError(\n\t\t\t\t\t\"http\",\n\t\t\t\t\t{ code: result.error.code, message: result.error.message, data: result.error.data },\n\t\t\t\t\ttraceId,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\treturn result.result as T;\n\t\t} catch (error) {\n\t\t\tif (operation.isTimeoutAbort(error) || operation.timedOut()) {\n\t\t\t\tthrow new MCPTransportError({\n\t\t\t\t\ttransport: \"http\",\n\t\t\t\t\tstage,\n\t\t\t\t\tfailure: \"timeout\",\n\t\t\t\t\tmessage: `Request timeout after ${timeout}ms`,\n\t\t\t\t\tretryable: false,\n\t\t\t\t\ttraceId,","sourceCodeStart":493,"sourceCodeEnd":529,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/mcp/transports/http.ts#L493-L529","documentation":"The JSON-RPC response contained an `error` member, but the error object itself was malformed — not an object, or its code is not a number / message is not a string as JSON-RPC 2.0 requires. The transport throws SyntaxError(\"Malformed JSON-RPC error response\") instead of fabricating a JSON-RPC error from invalid data.","triggerScenarios":"Server sends {jsonrpc:\"2.0\", id, error: ...} where error is a string, null, an object with non-numeric code (e.g. \"E123\"), or missing/non-string message.","commonSituations":"Server-side error serialization bugs; custom middleware converting errors to strings; protocol-version mismatch where the server emits a non-standard error shape; frameworks auto-wrapping exceptions incorrectly.","solutions":["Inspect server logs for the original error and fix the server's JSON-RPC error serialization (error must be {code:number, message:string, data?})","Align client and server on the same MCP/JSON-RPC protocol version","If a proxy transforms error bodies, bypass or fix the transformation","Catch the normalized decode-stage transport error and surface it to the user with trace context"],"exampleFix":"// before\n// server: {\"jsonrpc\":\"2.0\",\"id\":1,\"error\":\"boom\"}\n// after\n// server: {\"jsonrpc\":\"2.0\",\"id\":1,\"error\":{\"code\":-32603,\"message\":\"boom\"}}","handlingStrategy":"type-guard","validationCode":"// Conformance-test the server's error path before production:\nconst res = await callToolThatAlwaysFails();\nconst e = res.error;\nif (typeof e !== \"object\" || typeof e?.code !== \"number\" || typeof e?.message !== \"string\") throw new Error(\"server emits malformed JSON-RPC errors\");","typeGuard":"function isJsonRpcError(e: unknown): e is { code: number; message: string; data?: unknown } {\n  return typeof e === \"object\" && e !== null && typeof (e as any).code === \"number\" && typeof (e as any).message === \"string\";\n}","tryCatchPattern":"try {\n  await transport.request(method, params);\n} catch (err) {\n  if (err instanceof SyntaxError && err.message === \"Malformed JSON-RPC error response\") {\n    log.error(\"server JSON-RPC error serialization is non-conformant\");\n  } else throw err;\n}","preventionTips":["Fix server error serialization: error must be {code:number, message:string, data?}","Run JSON-RPC conformance checks against the server before release","Bypass middleware that stringifies error objects","Pin protocol versions on both sides"],"tags":["mcp","json-rpc","decode","protocol"],"backgroundTag":"malformed-json-rpc-response","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}