{"record":{"id":"42eabfa6d4236457","repo":"spacedriveapp/spacedrive","slug":"failed-to-parse-response","errorCode":null,"errorMessage":"Failed to parse response: {}","messagePattern":"Failed to parse response: (.+?)","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"apps/cli/src/domains/spaces/mod.rs","lineNumber":45,"sourceCode":"\tlet library_id = ctx.library_id.ok_or_else(|| {\n\t\tanyhow::anyhow!(\"No library selected. Run 'sd library list' to see available libraries\")\n\t})?;\n\n\tprintln!(\"Library ID: {}\", library_id);\n\n\t// Create query input\n\tlet input = SpacesListQueryInput;\n\n\t// Execute query through the client\n\tlet response = ctx.core.query(&input, Some(library_id)).await?;\n\n\tprintln!(\n\t\t\"\\nRaw response: {}\",\n\t\tserde_json::to_string_pretty(&response)?\n\t);\n\n\tlet result: sd_core::ops::spaces::SpacesListOutput = serde_json::from_value(response)\n\t\t.map_err(|e| anyhow::anyhow!(\"Failed to parse response: {}\", e))?;\n\n\tprintln!(\"\\nQuery executed successfully!\");\n\tprintln!(\"Found {} spaces:\", result.spaces.len());\n\n\tif result.spaces.is_empty() {\n\t\tprintln!(\"  (no spaces found)\");\n\t} else {\n\t\tlet mut table = Table::new();\n\t\ttable.load_preset(UTF8_BORDERS_ONLY);\n\t\ttable.set_header(vec![\"ID\", \"Name\", \"Icon\", \"Color\", \"Order\"]);\n\n\t\tfor space in result.spaces {\n\t\t\ttable.add_row(vec![\n\t\t\t\tCell::new(&space.id.to_string()[..8]),\n\t\t\t\tCell::new(&space.name),\n\t\t\t\tCell::new(&space.icon),\n\t\t\t\tCell::new(&space.color),\n\t\t\t\tCell::new(space.order),","sourceCodeStart":27,"sourceCodeEnd":63,"githubUrl":"https://github.com/spacedriveapp/spacedrive/blob/6dfeccf2113039e35f2ce735f945e70dc3e4ea45/apps/cli/src/domains/spaces/mod.rs#L27-L63","documentation":"Thrown when serde_json::from_value(response) fails to deserialize the daemon's JSON response for SpacesListQueryInput into SpacesListOutput. The wire payload's shape does not match the CLI's struct, which almost always means the CLI binary and the running daemon were built from different code (fields added/renamed/removed on one side).","triggerScenarios":"Running a freshly built sd-cli against a stale daemon that predates a change to SpacesListOutput; or vice versa; or a daemon returning an error envelope where the output object was expected.","commonSituations":"Developer rebuilt the CLI but forgot 'sd-cli restart' to restart the daemon with the new build; two checkouts of the repo at different commits; type changed on the backend without regenerating client-facing artifacts.","solutions":["Rebuild and restart the daemon so both sides run the same code: cargo build && cargo run --bin sd-cli -- restart","Read the raw response printed just above the error (the code pretty-prints response before parsing) to see which field mismatches","Verify CLI and daemon come from the same checkout/commit","If you changed backend types, regenerate the client-facing types with cargo run --bin generate_typescript_types where applicable"],"exampleFix":"// before: parse fails opaquely once the raw value is printed\nlet result: SpacesListOutput = serde_json::from_value(response)\n    .map_err(|e| anyhow::anyhow!(\"Failed to parse response: {}\", e))?;\n\n// after: include the mismatching field path and a version-skew hint\nlet result: SpacesListOutput = serde_json::from_value(response.clone()).map_err(|e| {\n    anyhow::anyhow!(\n        \"Failed to parse response: {} (raw={}); CLI/daemon version skew? Try 'sd-cli restart'\",\n        e,\n        serde_json::to_string(&response).unwrap_or_default()\n    )\n})?;","handlingStrategy":"try-catch","validationCode":"// Cheap pre-flight: ping the daemon version if available and compare before parsing\n// (no version endpoint needed if you simply keep CLI and daemon from one build)","typeGuard":"fn response_looks_like_spaces_list(v: &serde_json::Value) -> bool {\n    v.get(\"spaces\").map(|s| s.is_array()).unwrap_or(false)\n}","tryCatchPattern":"let result: SpacesListOutput = match serde_json::from_value(response.clone()) {\n    Ok(parsed) => parsed,\n    Err(e) => {\n        eprintln!(\"Response shape mismatch: {}\", e);\n        eprintln!(\"Raw: {}\", serde_json::to_string_pretty(&response).unwrap_or_default());\n        eprintln!(\"Likely CLI/daemon version skew - run: cargo run --bin sd-cli -- restart\");\n        return Err(e.into());\n    }\n};","preventionTips":["Always restart the daemon after rebuilding ('sd-cli restart') so both sides match","Ship CLI and daemon from the same commit in distributions","After changing output types, regenerate client artifacts before running the CLI"],"tags":["cli","spaces","serialization","version-skew","daemon"],"backgroundTag":null,"analyzedSha":"6dfeccf2113039e35f2ce735f945e70dc3e4ea45","analyzedAt":"2026-08-16T11:26:17.074Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}