spacedriveapp/spacedrive · error · anyhow::Error

Failed to parse response: {}

Error message

Failed to parse response: {}

What it means

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).

Source

Thrown at apps/cli/src/domains/spaces/mod.rs:45

	let library_id = ctx.library_id.ok_or_else(|| {
		anyhow::anyhow!("No library selected. Run 'sd library list' to see available libraries")
	})?;

	println!("Library ID: {}", library_id);

	// Create query input
	let input = SpacesListQueryInput;

	// Execute query through the client
	let response = ctx.core.query(&input, Some(library_id)).await?;

	println!(
		"\nRaw response: {}",
		serde_json::to_string_pretty(&response)?
	);

	let result: sd_core::ops::spaces::SpacesListOutput = serde_json::from_value(response)
		.map_err(|e| anyhow::anyhow!("Failed to parse response: {}", e))?;

	println!("\nQuery executed successfully!");
	println!("Found {} spaces:", result.spaces.len());

	if result.spaces.is_empty() {
		println!("  (no spaces found)");
	} else {
		let mut table = Table::new();
		table.load_preset(UTF8_BORDERS_ONLY);
		table.set_header(vec!["ID", "Name", "Icon", "Color", "Order"]);

		for space in result.spaces {
			table.add_row(vec![
				Cell::new(&space.id.to_string()[..8]),
				Cell::new(&space.name),
				Cell::new(&space.icon),
				Cell::new(&space.color),
				Cell::new(space.order),

View on GitHub (pinned to 6dfeccf211)

Solutions

  1. Rebuild and restart the daemon so both sides run the same code: cargo build && cargo run --bin sd-cli -- restart
  2. Read the raw response printed just above the error (the code pretty-prints response before parsing) to see which field mismatches
  3. Verify CLI and daemon come from the same checkout/commit
  4. If you changed backend types, regenerate the client-facing types with cargo run --bin generate_typescript_types where applicable

Example fix

// before: parse fails opaquely once the raw value is printed
let result: SpacesListOutput = serde_json::from_value(response)
    .map_err(|e| anyhow::anyhow!("Failed to parse response: {}", e))?;

// after: include the mismatching field path and a version-skew hint
let result: SpacesListOutput = serde_json::from_value(response.clone()).map_err(|e| {
    anyhow::anyhow!(
        "Failed to parse response: {} (raw={}); CLI/daemon version skew? Try 'sd-cli restart'",
        e,
        serde_json::to_string(&response).unwrap_or_default()
    )
})?;
Defensive patterns

Strategy: try-catch

Validate before calling

// Cheap pre-flight: ping the daemon version if available and compare before parsing
// (no version endpoint needed if you simply keep CLI and daemon from one build)

Type guard

fn response_looks_like_spaces_list(v: &serde_json::Value) -> bool {
    v.get("spaces").map(|s| s.is_array()).unwrap_or(false)
}

Try / catch

let result: SpacesListOutput = match serde_json::from_value(response.clone()) {
    Ok(parsed) => parsed,
    Err(e) => {
        eprintln!("Response shape mismatch: {}", e);
        eprintln!("Raw: {}", serde_json::to_string_pretty(&response).unwrap_or_default());
        eprintln!("Likely CLI/daemon version skew - run: cargo run --bin sd-cli -- restart");
        return Err(e.into());
    }
};

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Related errors


AI-assisted analysis of spacedriveapp/spacedrive@6dfeccf211 (2026-08-16). Data as JSON: /api/errors/42eabfa6d4236457. Report an issue: GitHub.