{"record":{"id":"559ef6b45a88e714","repo":"astrid-runtime/astrid","slug":"daemon-returned-an-unexpected-response-to-getcomma","errorCode":null,"errorMessage":"Daemon returned an unexpected response to GetCommands","messagePattern":"Daemon returned an unexpected response to GetCommands","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/astrid-cli/src/commands/capsule_verb.rs","lineNumber":200,"sourceCode":"        astrid_types::ipc::IpcPayload::RawJson(val),\n        source_id,\n    )\n    .with_principal(caller.to_string());\n    client.send_message(msg).await?;\n    let raw = client\n        .read_until_topic(\n            astrid_types::Topic::kernel_response(\"get_commands\").as_str(),\n            Duration::from_secs(10),\n        )\n        .await?;\n    match SocketClient::extract_kernel_response(&raw) {\n        Some(astrid_core::kernel_api::KernelResponse::Commands(cmds)) => Ok(cmds),\n        // Surface the daemon's own error (e.g. a capability/permission denial)\n        // instead of folding it into a generic \"unexpected response\".\n        Some(astrid_core::kernel_api::KernelResponse::Error(err)) => {\n            anyhow::bail!(\"Daemon error: {err}\")\n        },\n        _ => anyhow::bail!(\"Daemon returned an unexpected response to GetCommands\"),\n    }\n}\n\n/// Publish the run request and await + render the result.\nasync fn execute(provider: &str, verb: &str, args: &[String]) -> Result<ExitCode> {\n    let session = astrid_core::SessionId::from_uuid(Uuid::new_v4());\n    let source_id = session.0;\n    // Bind the connection to the active principal so the capsule verb runs\n    // under the invoking identity's context (VFS/KV/secrets), not the\n    // `default` (admin) principal a nil/unstamped message falls back to.\n    let caller = crate::principal::current();\n    let mut client =\n        match crate::socket_client::connect_for_workspace(session, caller.clone(), None).await {\n            Ok(c) => c,\n            Err(e) => {\n                eprintln!(\n                    \"{}\",\n                    Theme::error(&format!(\"Failed to connect to daemon: {e}\"))","sourceCodeStart":182,"sourceCodeEnd":218,"githubUrl":"https://github.com/astrid-runtime/astrid/blob/affd8760f44190dbdfbec23403f4c4b642c33112/crates/astrid-cli/src/commands/capsule_verb.rs#L182-L218","documentation":"When the CLI resolves the list of capsule commands, it sends a `get_commands` kernel request over the IPC socket and expects the daemon to reply with a KernelResponse::Commands payload. This error is thrown when the daemon's reply is neither Commands nor an explicit KernelResponse::Error — i.e. the response shape does not match what the CLI's GetCommands handler can interpret. It indicates a protocol/version mismatch between CLI and daemon, a corrupted/interleaved frame, or the request never reaching the kernel's command resolver.","triggerScenarios":"Calling any `astrid` capsule verb that runs resolve_commands (via run_external or run_explicit) when the daemon replies to the get_commands topic with a payload that deserializes to a KernelResponse variant other than Commands or Error (e.g. an empty, malformed, or unrelated response, or a daemon built from a different version).","commonSituations":"Mixed-version installs where the daemon binary was updated but a stale daemon from an older version is still running; a proxy/middleware on the socket rewriting frames; another client interleaving messages on the same connection so extract_kernel_response picks up the wrong frame.","solutions":["Restart the daemon so CLI and daemon versions match: run `astrid restart` (or kill the daemon process and let the next command spawn a fresh one).","Verify the astrid-cli and astrid-core/daemon binaries come from the same build (`astrid --version` vs the daemon binary's version) and reinstall/rebuild together.","Check the daemon boot log for panics or protocol errors around the get_commands request, then retry the command.","If the error is reproducible on a fresh daemon, file a bug with the raw frame; the variant returned by extract_kernel_response indicates what broke the protocol contract."],"exampleFix":"// before: single shared daemon across mixed versions\n$ astrid daemon start   # old binary still running\n$ astrid run mycapsule cmd  # Daemon returned an unexpected response to GetCommands\n// after\n$ astrid restart        # kills stale daemon, spawns matching build\n$ astrid run mycapsule cmd  # OK","handlingStrategy":"try-catch","validationCode":"// Pre-check daemon/CLI version agreement and liveness before running capsule verbs\nasync fn daemon_compatible(client: &mut SocketClient) -> anyhow::Result<bool> {\n    let raw = client.read_until_topic(Topic::kernel_response(\"ping\").as_str(), Duration::from_secs(5)).await?;\n    Ok(SocketClient::extract_kernel_response(&raw)\n        .map(|r| matches!(r, KernelResponse::Commands(_) | KernelResponse::Pong))\n        .unwrap_or(false))\n}","typeGuard":"fn is_expected_kernel_response(raw: &[u8]) -> Option<KernelResponse> {\n    serde_json::from_slice::<KernelResponse>(raw).ok()\n        .filter(|r| matches!(r, KernelResponse::Commands(_) | KernelResponse::Error(_)))\n}","tryCatchPattern":"match resolve_commands(client).await {\n    Ok(cmds) => render(cmds),\n    Err(e) if e.to_string().contains(\"unexpected response to GetCommands\") => {\n        eprintln!(\"CLI/daemon protocol mismatch; run `astrid restart`\");\n        // optionally retry once after restart\n    },\n    Err(e) => return Err(e),\n}","preventionTips":["Always start/restart the daemon with the same build as the CLI (avoid mixed-version installs).","Run `astrid restart` after upgrading any astrid binary.","Check daemon logs when any IPC response looks malformed.","Pin daemon and CLI versions together in deployment scripts."],"tags":["ipc","protocol-mismatch","daemon","cli"],"backgroundTag":"unexpected-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"}