rust-lang/rust-analyzer · error

Unable to deserialize message

Error message

Unable to deserialize message

What it means

An `expect` message on `serde_json::from_str` in the `test_deserialization` unit test: it fails when the inline JSON-LD-style discover message fixture cannot be parsed into `DiscoverProjectData`. Because it sits in a test, it fires only when the serde derive on `DiscoverProjectData` (field renames, snake_case tagging, shape) drifts out of sync with the documented wire format — the input at fault is the fixture JSON and the enum's serde attributes.

Source

Thrown at crates/rust-analyzer/src/discover.rs:152

    }

    fn from_eof(&self) -> Option<DiscoverProjectMessage> {
        None
    }

    fn from_stderr_line(&self, line: &str, _error: &mut String) -> Option<DiscoverProjectMessage> {
        tracing::info!(%line, "discover command stderr");
        None
    }
}

#[test]
fn test_deserialization() {
    let message = r#"
    {"kind": "progress", "message":"querying build system","input":{"files":["src/main.rs"]}}
    "#;
    let message: DiscoverProjectData =
        serde_json::from_str(message).expect("Unable to deserialize message");
    assert!(matches!(message, DiscoverProjectData::Progress { .. }));

    let message = r#"
    {"kind": "error", "error":"failed to deserialize command output","source":"command"}
    "#;

    let message: DiscoverProjectData =
        serde_json::from_str(message).expect("Unable to deserialize message");
    assert!(matches!(message, DiscoverProjectData::Error { .. }));

    let message = r#"
    {"kind": "finished", "project": {"sysroot": "foo", "crates": [], "runnables": []}, "buildfile":"rust-analyzer/BUILD"}
    "#;

    let message: DiscoverProjectData =
        serde_json::from_str(message).expect("Unable to deserialize message");
    assert!(matches!(message, DiscoverProjectData::Finished { .. }));
}

View on GitHub (pinned to e8f7e90aa3)

Solutions

  1. Compare the fixture JSON keys with the `#[serde(...)]` attributes on `DiscoverProjectData` after any change to the wire format
  2. Update the fixture to match the current snake_case/`kind` tag encoding when the protocol evolves intentionally
  3. Add fixtures for each message variant (finished/error/progress) so deserialization drift is caught per-variant
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at crates/rust-analyzer/src/discover.rs:152 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of rust-lang/rust-analyzer@e8f7e90aa3 (2026-09-03). Data as JSON: /api/errors/b5360bebc4c706b8. Report an issue: GitHub.