rust-lang/rust-analyzer · warning

serialized runnable

Error message

serialized runnable

What it means

A unit test asserts that the Runnable struct serializes to JSON without failing. serde_json::to_value returns Err only if a map key is not a string or serialization is otherwise impossible; the expect turns that into a panic labeled "serialized runnable". Failure indicates the Runnable/RunnableArgs serde derive or a manual Serialize impl is broken.

Source

Thrown at crates/rust-analyzer/src/lsp/ext.rs:1005

                    "--lib".into(),
                ],
                executable_args: vec!["my_test".into(), "--exact".into()],
            }),
        };
        let expected = json!({
            "label": "cargo test -p my-crate",
            "kind": "cargo",
            "args": {
                "environment": {"RUSTC_TOOLCHAIN": "/toolchain"},
                "cwd": "/project",
                "overrideCargo": null,
                "workspaceRoot": "/project",
                "cargoArgs": ["test", "--package", "my-crate", "--lib"],
                "executableArgs": ["my_test", "--exact"],
            }
        });

        let serialized = serde_json::to_value(&runnable).expect("serialized runnable");
        assert_eq!(serialized, expected);

        let deserialized: Runnable =
            serde_json::from_value(expected).expect("cargo runnable should deserialize");
        let RunnableArgs::Cargo(cargo) = &deserialized.args else {
            panic!("expected Cargo variant, got {:?}", deserialized.args);
        };
        assert_eq!(cargo.cargo_args, vec!["test", "--package", "my-crate", "--lib"]);
        assert_eq!(cargo.executable_args, vec!["my_test", "--exact"]);
    }

    #[test]
    fn shell_runnable_round_trips() {
        let runnable = Runnable {
            label: "nextest test_one".to_owned(),
            location: None,
            args: RunnableArgs::Shell(ShellRunnableArgs {
                environment: [("RUSTC_TOOLCHAIN".to_owned(), "/toolchain".to_owned())]

View on GitHub (pinned to e8f7e90aa3)

Solutions

  1. Run the failing test with RUST_BACKTRACE=1 to locate which field's Serialize impl errors.
  2. Fix the Serialize implementation/serde attributes on Runnable or its args so to_value cannot fail (all map keys must be strings).
  3. Regenerate/adjust the expected JSON in the test only after confirming the new wire format is intended.
  4. If the extension protocol intentionally changed, update the client extension's expected payload shape too.
Defensive patterns

Strategy: validation

Validate before calling

// in the test, surface the underlying serde error instead of an opaque panic
let serialized = serde_json::to_value(&runnable)
    .unwrap_or_else(|e| panic!("runnable failed to serialize: {e}"));

Type guard

fn serializable<T: serde::Serialize>(v: &T) -> bool {
    serde_json::to_value(v).is_ok()
}

Prevention

When it happens

Trigger: Modifying the Runnable, RunnableArgs (Cargo/Shell), or related lsp_ext types so serde_json::to_value fails — e.g. a non-string map key or a Serialize impl returning an error — then running cargo test -p rust-analyzer in crates/rust-analyzer/src/lsp/ext.rs.

Common situations: Contributors changing the rust-analyzer LSP extension API (runnable payload schema), switching serde attributes (untagged/adjacent tagging), or adding types that cannot serialize to JSON.

Related errors


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