biomejs/biome · error · Error
failed to deserialize incoming message from remote workspace
Error message
failed to deserialize incoming message from remote workspace, "${data}" is not a valid JSON-RPC message body What it means
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).
Source
Thrown at packages/@biomejs/backend-jsonrpc/src/transport.ts:289
const pendingRequest = this.pendingRequests.get(body.id);
if (pendingRequest) {
this.pendingRequests.delete(body.id);
const { resolve, reject } = pendingRequest;
if ("result" in body) {
resolve(body.result);
} else {
reject(body.error);
}
} else {
throw new Error(
`could not find any pending request matching RPC response ID ${body.id}`,
);
}
return;
}
}
throw new Error(
`failed to deserialize incoming message from remote workspace, "${data}" is not a valid JSON-RPC message body`,
);
}
}
View on GitHub (pinned to 7529811358)
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.
Example fix
// before: peer answers with a bare JSON object
socket.write(frame({ status: "ok" }));
// after: peer answers with a JSON-RPC 2.0 envelope echoing the request id
socket.write(frame({ jsonrpc: "2.0", id: requestId, result: { status: "ok" } })); Defensive patterns
Strategy: validation
Validate before calling
// Peer-side guard: validate every outgoing frame is a JSON-RPC 2.0 envelope with byte-accurate framing
function frame(message) {
if (message.jsonrpc !== "2.0") throw new Error("outgoing message must carry jsonrpc: '2.0'");
if ("method" in message && typeof message.id === "number") {
// request: fine
} else if ("method" in message) {
// notification: fine
} else if (typeof message.id === "number" && ("result" in message || "error" in message)) {
// response: fine
} else {
throw new Error("outgoing message matches no JSON-RPC 2.0 shape");
}
const body = Buffer.from(JSON.stringify(message));
return Buffer.concat([Buffer.from(`Content-Length: ${body.length}\r\n\r\n`), body]);
} Type guard
// Mirrors the receiver's guards (transport.ts:33-92)
function isJsonRpcResponse(message) {
return (
typeof message === "object" &&
message !== null &&
message.jsonrpc === "2.0" &&
typeof message.id === "number" &&
!("method" in message) &&
("result" in message || "error" in message)
);
} Try / catch
process.on("uncaughtException", (err) => {
if (err.message.includes("is not a valid JSON-RPC message body")) {
// The peer's envelope is wrong; log the embedded body and fail the connection.
transport.destroy();
} else {
throw err;
}
}); Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- incoming message from the remote workspace is missing the Co
- could not find colon token in "${line}"
- invalid value for Content-Type expected "${MIME_JSONRPC}", g
- could not find any pending request matching RPC response ID
- Failed to parse URI {}: {e}
AI-assisted analysis of biomejs/biome@7529811358 (2026-08-16).
Data as JSON: /api/errors/7d49e409702cf6c8.
Report an issue: GitHub.