zed-industries/zed · error · anyhow::Error
failed to deserialize response
Error message
failed to deserialize response
What it means
This error occurs in Zed's LSP client when a JSON-RPC response from a language server cannot be deserialized into the expected strongly-typed result of the request (e.g. a `lsp::CompletionResponse` or `lsp::Hover`). The client wraps the serde/serde_json error with the context string "failed to deserialize response", and the future returned by `LanguageServer::request` resolves to this error. It indicates the server replied, but the payload shape did not match the LSP schema Zed expected — usually a server that emits non-conformant JSON, or a Zed-side type mismatch between the lsp-types version and what the server sends.
Source
Thrown at crates/lsp/src/lsp.rs:1552
.lock()
.as_mut()
.context("server shut down")
.map(|handlers| {
let executor = executor.clone();
handlers.insert(
RequestId::Int(id),
Box::new(move |result| {
executor
.spawn(async move {
let response = match result {
Ok(response) => match deserialize_result(&response) {
Ok(deserialized) => Ok(deserialized),
Err(error) => {
log::error!("failed to deserialize response from language server: {}. response from language server: {:?}", error, response);
Err(error).context("failed to deserialize response")
}
}
Err(error) => Err(anyhow::Error::new(error)),
};
tx.send(response).ok();
})
}),
);
});
let send = outbound_tx
.try_send(message)
.context("failed to write to language server's stdin");
let response_handlers = Arc::clone(response_handlers);
let notification_serializers = notification_serializers.downgrade();
let started = Instant::now();
LspRequest::new(id, async move {
if let Err(e) = handle_response {
return ConnectionResult::Result(Err(e));
}View on GitHub (pinned to 9d272b0363)
Solutions
- Check the Zed log (the `log::error!` at crates/lsp/src/lsp.rs:1545 includes the raw server response) to see the exact serde error and offending payload.
- Update the language server binary to a released version; non-conformant responses are often fixed upstream.
- Update Zed (or lsp-types/zed's LSP adapter) so its expected response types match the server's LSP dialect.
- If a specific server is at fault, file/lookup an issue on the server; as a workaround, disable or downgrade that extension/server version.
- If you develop the adapter (languages/src/*_language_server), normalize the server's quirks in the adapter before the response reaches the typed request path.
Defensive patterns
Strategy: try-catch
Validate before calling
// No pre-call validation is possible: the payload shape is decided by the server.
// Log the raw response at the adapter layer to make failures debuggable:
tracing::debug!(response = %raw_response_json, "server response for {}", T::METHOD); Type guard
fn is_deserialize_failure(err: &anyhow::Error) -> bool {
err.chain().any(|c| c.to_string().contains("failed to deserialize response"))
} Try / catch
match server.request::<lsp::request::Completion>(¶ms).await {
Ok(result) => result,
Err(err) if is_deserialize_failure(&err) => {
log::warn!("server sent non-conformant response: {err:#}");
Default::default() // fall back to empty completion result
}
Err(err) => return Err(err),
} Prevention
- Keep Zed and its language server binaries updated together so lsp-types expectations match the server.
- When a server misbehaves, read the full raw response in Zed's log line "failed to deserialize response from language server" to identify the offending field.
- Pin known-good language server versions in project settings for servers with LSP conformance bugs.
- Report conformance bugs upstream with the logged raw response.
When it happens
Trigger: Calling `LanguageServer::request::<T>()` (crates/lsp/src/lsp.rs `request_internal_with_timer`, line 1542 `deserialize_result`) where the server's response body fails `serde_json` deserialization into `T::Result` — e.g. a server returning `null` result for a non-nullable request type, a completion item with wrong-typed fields, unknown enum variant, or missing required fields.
Common situations: Using a language server version that emits LSP 3.17+ fields Zed's pinned lsp-types version rejects or a server with known spec violations (e.g. some Rust Analyzer/clangd/gopls edge responses, jdtls returning null results for textDocument/documentSymbol); server extensions that add fields with wrong types; running a dev build of a language server against a newer Zed or vice versa.
Related errors
- incorrect proto inlay hint message: no resolve state in hint
- verifier produced no results (exit {completed.returncode}):
- Failed to parse example file: {} {error}
- unrecognized serialized thread version: {version:?}
- Expected exactly one context server configuration
AI-assisted analysis of zed-industries/zed@9d272b0363 (2026-09-05).
Data as JSON: /api/errors/190dcc441fc8e3db.
Report an issue: GitHub.