astrid-runtime/astrid · error
daemon returned an unexpected status response: {other:?}
Error message
daemon returned an unexpected status response: {other:?} What it means
status_response expects KernelResponse::Status for a GetStatus request; any other successful-shaped variant (e.g. Success, capsule-specific responses) is a protocol-level mismatch. The CLI bails with the debug representation of the unexpected response so the developer can see which variant arrived.
Source
Thrown at crates/astrid-cli/src/commands/daemon.rs:653
println!(" - {capsule}");
}
Ok(())
}
fn status_document(status: Option<&DaemonStatus>) -> serde_json::Value {
status.map_or_else(
|| serde_json::json!({ "state": "stopped" }),
|status| serde_json::json!({ "state": "running", "daemon": status }),
)
}
fn status_response(response: KernelResponse) -> Result<DaemonStatus> {
match response {
KernelResponse::Status(status) => Ok(status),
KernelResponse::Error(message) => {
anyhow::bail!("daemon rejected status request: {message}")
},
other => anyhow::bail!("daemon returned an unexpected status response: {other:?}"),
}
}
/// Handle `astrid stop`.
///
/// A shutdown request over the socket only earns an ACK ("shutting down"), not a
/// guarantee the process exited and released the singleton/state-db lock. So we
/// capture the recorded PID BEFORE asking, then confirm the process actually
/// exits — escalating with a signal if it wedges mid-shutdown — before reporting
/// success. Runtime files (socket, readiness, PID) are removed only once the
/// daemon is confirmed gone; if a kill can't confirm exit, they are LEFT so
/// `astrid start`/`restart` still see the recorded PID and give an actionable
/// message instead of failing on the held lock with a raw DB error.
pub(crate) async fn handle_stop() -> Result<()> {
validate_runtime_admission()?;
// A pre-lease gateway may legitimately hold the start fence while it boots
// its daemon. Stop the gateway first so stop can reap it; then the fence
// linearizes the daemon phase against any other start/restart.View on GitHub (pinned to affd8760f4)
Solutions
- Check version skew: compare `astrid --version` with the running daemon's PID binary (ps -p <pid> -o cmdline) and align versions.
- Run `astrid restart` so the daemon binary matches the CLI's protocol expectations.
- Ensure no other process is bound to the Astrid socket path.
- Rebuild/reinstall so CLI and daemon come from the same build.
Example fix
// before $ astrid --version # v2 CLI $ astrid status Error: daemon returned an unexpected status response: Success(...) // after $ astrid restart # respawn daemon from the same v2 build $ astrid status
Defensive patterns
Strategy: try-catch
Validate before calling
// detect version skew before querying
let cli_version = env!("CARGO_PKG_VERSION");
let daemon_version = /* from a prior handshake or `astrid status` once healthy */;
if cli_version != daemon_version { run(vec!["astrid", "restart"])?; } Type guard
fn is_status(resp: &KernelResponse) -> bool {
matches!(resp, KernelResponse::Status(_))
} Try / catch
match status_response(client.request(KernelRequest::GetStatus).await?) {
Ok(s) => s,
Err(e) if e.to_string().contains("unexpected status response") => {
run(vec!["astrid", "restart"])?; // respawn version-matched daemon
status_response(client.request(KernelRequest::GetStatus).await?)?
}
Err(e) => return Err(e),
} Prevention
- Always `astrid restart` after upgrading the CLI so the daemon binary matches.
- Ensure only one astrid build is on PATH; remove stale installs.
- Check that no wrapper/gateway process is bound to the Astrid socket.
- Pin daemon+CLI versions together in deployment manifests.
When it happens
Trigger: KernelRequest::GetStatus answered with a KernelResponse variant other than Status or Error — typically a version-skewed daemon binary speaking a different protocol, or a proxy/relay answering with its own response type.
Common situations: Older daemon still running after a CLI upgrade (protocol drift); mixing CLI and daemon from different versions/install paths; a gateway or wrapper intercepting socket traffic and returning its own response variant.
Related errors
- unexpected daemon response: {other:?}
- unexpected daemon response: {other:?}
- running daemon returned unknown unload status {other:?}
- running daemon returned unload success without a status
- unexpected daemon response: {other:?}
AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09).
Data as JSON: /api/errors/1d32795c3bd6d4ea.
Report an issue: GitHub.