{"record":{"id":"415837a87b660c1b","repo":"rust-lang/rust-analyzer","slug":"shell-runnable-should-deserialize","errorCode":null,"errorMessage":"shell runnable should deserialize","messagePattern":"shell runnable should deserialize","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"crates/rust-analyzer/src/lsp/ext.rs","lineNumber":1048,"sourceCode":"        };\n        let expected = json!({\n            \"label\": \"nextest test_one\",\n            \"kind\": \"shell\",\n            \"args\": {\n                \"environment\": {\"RUSTC_TOOLCHAIN\": \"/toolchain\"},\n                \"cwd\": \"/project\",\n                \"program\": \"cargo\",\n                \"args\": [\"nextest\", \"run\", \"--package\", \"my-crate\"],\n            }\n        });\n\n        let serialized = serde_json::to_value(&runnable).expect(\"serialized runnable\");\n        assert_eq!(serialized, expected);\n\n        // Every shell runnable is a structurally valid cargo runnable if the `kind` tag isn't\n        // used. This test ensures that the `kind` tag is used.\n        let deserialized: Runnable =\n            serde_json::from_value(expected).expect(\"shell runnable should deserialize\");\n        let RunnableArgs::Shell(shell) = &deserialized.args else {\n            panic!(\"expected Shell variant, got {:?}\", deserialized.args);\n        };\n        assert_eq!(shell.program, \"cargo\");\n        assert_eq!(shell.args, vec![\"nextest\", \"run\", \"--package\", \"my-crate\"]);\n    }\n}\n","sourceCodeStart":1030,"sourceCodeEnd":1056,"githubUrl":"https://github.com/rust-lang/rust-analyzer/blob/e8f7e90aa3e7b26aa9a000200f606c1078da99ec/crates/rust-analyzer/src/lsp/ext.rs#L1030-L1056","documentation":"The shell-runnable deserialization half of the round-trip test: from_value(expected) must produce RunnableArgs::Shell. A panic means the fixture JSON does not deserialize under the current serde schema — typically because the `kind` tag is missing or renamed, letting the payload be misread as (or fail as) a Cargo variant.","triggerScenarios":"Removing or renaming the `kind` tag in the Runnable serde representation, renaming program/args fields without updating the fixture, or switching the enum tagging strategy so the shell JSON no longer selects RunnableArgs::Shell.","commonSituations":"Refactoring the lsp_ext Runnable types, new contributors unfamiliar with the test's stated invariant (every shell runnable must be distinguishable from a cargo runnable only via the `kind` tag).","solutions":["Restore/keep the internally-tagged representation: #[serde(tag = \"kind\")] with a Shell discriminant.","Sync the fixture JSON field names with the current struct field names (program, args, cwd, etc.).","Read the serde error via RUST_BACKTRACE=1 or by replacing expect with match to see the exact mismatch.","Regenerate expectations with UPDATE_EXPECT=1 only after confirming the new schema, and mirror it in the client extension."],"exampleFix":"// before: fixture without discriminant\n{ \"cwd\": \"/project\", \"program\": \"cargo\", \"args\": [\"nextest\"] }\n// after: include the kind tag the schema requires\n{ \"kind\": \"shell\", \"cwd\": \"/project\", \"program\": \"cargo\", \"args\": [\"nextest\"] }","handlingStrategy":"type-guard","validationCode":"// ensure the fixture selects the Shell variant before deserializing\nassert_eq!(expected.get(\"kind\").and_then(|k| k.as_str()), Some(\"shell\"),\n    \"shell runnable fixture must use the kind tag\");","typeGuard":"fn is_shell_runnable(v: &serde_json::Value) -> bool {\n    v.get(\"kind\").and_then(|k| k.as_str()) == Some(\"shell\")\n        && v.get(\"program\").map(|p| p.is_string()).unwrap_or(false)\n}","tryCatchPattern":null,"preventionTips":["Never remove or rename the `kind` discriminant on RunnableArgs.","Keep test fixtures in lockstep with struct field names.","Read the serde error message before rewriting expectations.","Run UPDATE_EXPECT=1 only after manually reviewing the diff."],"tags":["tests","serde","deserialization","lsp-ext"],"backgroundTag":"serde-deserialization-schema-mismatch","analyzedSha":"e8f7e90aa3e7b26aa9a000200f606c1078da99ec","analyzedAt":"2026-09-03T21:08:06.959Z","contentChangedAt":"2026-09-03T21:08:06.959Z","schemaVersion":2},"datasetVersion":"2026-09-11T07:07:21.782Z"}