{"record":{"id":"7affcd60f40f0156","repo":"astrid-runtime/astrid","slug":"unexpected-daemon-response-other-7affcd","errorCode":null,"errorMessage":"unexpected daemon response: {other:?}","messagePattern":"unexpected daemon response: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/astrid-cli/src/commands/capsule/install_update.rs","lineNumber":180,"sourceCode":"            workspace,\n            false,\n            approve_untrusted,\n            &[],\n        )\n        .await\n    } else {\n        update_all_capsules(&home, &principal, workspace, approve_untrusted).await\n    }\n}\n\nasync fn daemon_capsule_metadata() -> anyhow::Result<Vec<CapsuleMetadataEntry>> {\n    let mut client = crate::socket_client::connect_kernel_for_workspace(None).await?;\n    match client.request(KernelRequest::GetCapsuleMetadata).await? {\n        KernelResponse::CapsuleMetadata(entries) => Ok(entries),\n        KernelResponse::Error(message) => {\n            bail!(\"daemon rejected capsule metadata request: {message}\")\n        },\n        other => bail!(\"unexpected daemon response: {other:?}\"),\n    }\n}\n\nasync fn update_daemon_capsules(\n    target: Option<&str>,\n    principal: &astrid_core::PrincipalId,\n    approve_untrusted: bool,\n) -> anyhow::Result<()> {\n    let entries = daemon_capsule_metadata().await?;\n    if let Some(name) = target {\n        let entry = entries\n            .into_iter()\n            .find(|entry| entry.name == name)\n            .ok_or_else(|| anyhow::anyhow!(\"Capsule '{name}' is not installed.\"))?;\n        let Some(source) = entry.update_source else {\n            eprintln!(\n                \"Capsule '{name}' has no remotely updateable source; its durable package is unchanged.\"\n            );","sourceCodeStart":162,"sourceCodeEnd":198,"githubUrl":"https://github.com/astrid-runtime/astrid/blob/affd8760f44190dbdfbec23403f4c4b642c33112/crates/astrid-cli/src/commands/capsule/install_update.rs#L162-L198","documentation":"Raised by `daemon_capsule_metadata` when the daemon replies to `GetCapsuleMetadata` with neither `CapsuleMetadata` nor `Error` — i.e. an unexpected `KernelResponse` variant. This indicates a protocol mismatch between CLI and daemon: the response does not fit the expected request/response contract, so it is dumped with `{other:?}` debug formatting.","triggerScenarios":"Running `astrid capsule update` or distro-lock regeneration against a daemon whose response to GetCapsuleMetadata is a different KernelResponse variant — typically a daemon/CLI version skew where the old daemon answers a newer request type with a generic Success/other payload, or a proxy/misrouted socket reply.","commonSituations":"CLI upgraded but daemon still running an older binary (socket not restarted); multiple daemons or a stale socket file routing requests to the wrong process; custom/patched daemon builds with divergent response types.","solutions":["Restart the daemon so it matches the CLI's protocol version, then retry.","Check versions: update the daemon (`astrid daemon` upgrade/reinstall) after any CLI upgrade.","Inspect the debug payload in the message (`{other:?}`) to identify which variant was returned and why.","Remove stale socket files / ensure only one daemon instance is running for the workspace."],"exampleFix":"// before: old daemon answers new CLI's request with a legacy payload\nastrid capsule update\n// error: unexpected daemon response: Success({...})\n\n// after\nastrid daemon restart   # run the upgraded daemon binary\nastrid capsule update","handlingStrategy":"try-catch","validationCode":null,"typeGuard":"fn is_capsule_metadata(resp: &KernelResponse) -> Option<&Vec<CapsuleMetadataEntry>> {\n    match resp {\n        KernelResponse::CapsuleMetadata(entries) => Some(entries),\n        _ => None,\n    }\n}","tryCatchPattern":"match daemon_capsule_metadata().await {\n    Ok(entries) => use_entries(entries),\n    Err(e) if e.to_string().starts_with(\"unexpected daemon response\") => {\n        eprintln!(\"{e:#}\\nProtocol mismatch - restart/upgrade the daemon.\");\n        std::process::exit(1);\n    },\n    Err(e) => return Err(e),\n}","preventionTips":["Keep daemon and CLI versions locked in step; restart the daemon after every CLI upgrade.","Remove stale socket files so requests cannot reach an outdated daemon process.","Run a single daemon instance per workspace.","Log unexpected KernelResponse payloads to spot protocol drift early."],"tags":["daemon","ipc","protocol"],"backgroundTag":"unexpected-api-response-shape","analyzedSha":"affd8760f44190dbdfbec23403f4c4b642c33112","analyzedAt":"2026-09-09T21:28:12.402Z","contentChangedAt":"2026-09-09T21:28:12.402Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}