{"record":{"id":"7d49e409702cf6c8","repo":"biomejs/biome","slug":"failed-to-deserialize-incoming-message-from-remote","errorCode":null,"errorMessage":"failed to deserialize incoming message from remote workspace, \"${data}\" is not a valid JSON-RPC message body","messagePattern":"failed to deserialize incoming message from remote workspace, \"(.+?)\" is not a valid JSON-RPC message body","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/@biomejs/backend-jsonrpc/src/transport.ts","lineNumber":289,"sourceCode":"\t\t\t\tconst pendingRequest = this.pendingRequests.get(body.id);\n\t\t\t\tif (pendingRequest) {\n\t\t\t\t\tthis.pendingRequests.delete(body.id);\n\t\t\t\t\tconst { resolve, reject } = pendingRequest;\n\t\t\t\t\tif (\"result\" in body) {\n\t\t\t\t\t\tresolve(body.result);\n\t\t\t\t\t} else {\n\t\t\t\t\t\treject(body.error);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t`could not find any pending request matching RPC response ID ${body.id}`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\tthrow new Error(\n\t\t\t`failed to deserialize incoming message from remote workspace, \"${data}\" is not a valid JSON-RPC message body`,\n\t\t);\n\t}\n}\n","sourceCodeStart":271,"sourceCodeEnd":294,"githubUrl":"https://github.com/biomejs/biome/blob/7529811358079edb5a2a9d4a5f67a9f639a63f3a/packages/@biomejs/backend-jsonrpc/src/transport.ts#L271-L294","documentation":"After a body frame is extracted and JSON.parse succeeds (a SyntaxError from JSON.parse at transport.ts:257 is a different failure), the parsed object is validated against the JSON-RPC 2.0 shapes: it must have jsonrpc === \"2.0\" (isJsonRpcMessage) and match a request, notification, or response guard (transport.ts:33-92). If none match, the message is unusable and this error is thrown with the raw body embedded (transport.ts:289-291).","triggerScenarios":"The peer sends valid JSON that is not JSON-RPC 2.0: missing 'jsonrpc': '2.0' envelope; a response with a string id; a message with neither result nor error; or a truncated/concatenated body caused by an incorrect Content-Length that happens to still parse as JSON.","commonSituations":"The socket is wired to a plain JSON service instead of the daemon; Content-Length computed from UTF-16 string length instead of byte length truncates multi-byte messages; a daemon/client version mismatch changes the message envelope.","solutions":["Inspect the data string included in the error message to see exactly what envelope the peer actually sent.","Fix the sender to emit full JSON-RPC 2.0 envelopes: jsonrpc: \"2.0\", numeric ids, and result or error on responses.","When framing outgoing messages, set Content-Length to the Buffer byte length of the body, not the JS string length.","Verify the connected process is the Biome daemon and its version matches the client package."],"exampleFix":"// before: peer answers with a bare JSON object\nsocket.write(frame({ status: \"ok\" }));\n\n// after: peer answers with a JSON-RPC 2.0 envelope echoing the request id\nsocket.write(frame({ jsonrpc: \"2.0\", id: requestId, result: { status: \"ok\" } }));","handlingStrategy":"validation","validationCode":"// Peer-side guard: validate every outgoing frame is a JSON-RPC 2.0 envelope with byte-accurate framing\nfunction frame(message) {\n\tif (message.jsonrpc !== \"2.0\") throw new Error(\"outgoing message must carry jsonrpc: '2.0'\");\n\tif (\"method\" in message && typeof message.id === \"number\") {\n\t\t// request: fine\n\t} else if (\"method\" in message) {\n\t\t// notification: fine\n\t} else if (typeof message.id === \"number\" && (\"result\" in message || \"error\" in message)) {\n\t\t// response: fine\n\t} else {\n\t\tthrow new Error(\"outgoing message matches no JSON-RPC 2.0 shape\");\n\t}\n\tconst body = Buffer.from(JSON.stringify(message));\n\treturn Buffer.concat([Buffer.from(`Content-Length: ${body.length}\\r\\n\\r\\n`), body]);\n}","typeGuard":"// Mirrors the receiver's guards (transport.ts:33-92)\nfunction isJsonRpcResponse(message) {\n\treturn (\n\t\ttypeof message === \"object\" &&\n\t\tmessage !== null &&\n\t\tmessage.jsonrpc === \"2.0\" &&\n\t\ttypeof message.id === \"number\" &&\n\t\t!(\"method\" in message) &&\n\t\t(\"result\" in message || \"error\" in message)\n\t);\n}","tryCatchPattern":"process.on(\"uncaughtException\", (err) => {\n\tif (err.message.includes(\"is not a valid JSON-RPC message body\")) {\n\t\t// The peer's envelope is wrong; log the embedded body and fail the connection.\n\t\ttransport.destroy();\n\t} else {\n\t\tthrow err;\n\t}\n});","preventionTips":["Always include jsonrpc: \"2.0\" and a numeric id in responses; include result or error, never neither.","Set Content-Length from byte length so multi-byte JSON is never truncated into a different shape.","Smoke-test the peer with one request/response round trip before long-running sessions, so envelope mistakes surface immediately."],"tags":["jsonrpc","transport","serialization","protocol","message-validation"],"backgroundTag":"jsonrpc-message-validation","analyzedSha":"7529811358079edb5a2a9d4a5f67a9f639a63f3a","analyzedAt":"2026-08-16T22:13:27.842Z","schemaVersion":2},"datasetVersion":"2026-08-16T23:17:17.608Z"}