astrid-runtime/astrid · error
daemon returned an unexpected status response
Error message
daemon returned an unexpected status response
What it means
The doctor command sends a KernelRequest::Status over the daemon socket and matches on the reply. If the daemon replies with any KernelResponse variant other than Status or Error, this anyhow error is thrown. It means the daemon is reachable and answered, but with a response type the doctor's status check does not understand.
Source
Thrown at crates/astrid-cli/src/commands/doctor.rs:244
async fn daemon_roundtrip() -> Result<()> {
let mut client = tokio::time::timeout(
Duration::from_secs(5),
crate::socket_client::connect_kernel_for_workspace(None),
)
.await
.map_err(|_| anyhow::anyhow!("connection timed out after 5s"))??;
match tokio::time::timeout(
Duration::from_secs(5),
client.request(KernelRequest::GetStatus),
)
.await
.map_err(|_| anyhow::anyhow!("daemon response timed out after 5s"))??
{
KernelResponse::Status(_) => Ok(()),
KernelResponse::Error(message) => {
Err(anyhow::anyhow!("daemon rejected status request: {message}"))
},
_ => Err(anyhow::anyhow!(
"daemon returned an unexpected status response"
)),
}
}
/// Query the daemon for agent-loop readiness over the same socket the
/// other daemon-dependent checks use. Rides the existing
/// `astrid.v1.request.` ingress allowlist prefix — no capsule change needed.
async fn agent_readiness() -> Result<astrid_core::kernel_api::AgentLoopReadiness> {
let mut client = tokio::time::timeout(
Duration::from_secs(5),
crate::socket_client::connect_kernel_for_workspace(None),
)
.await
.map_err(|_| anyhow::anyhow!("connection timed out after 5s"))??;
match tokio::time::timeout(
Duration::from_secs(5),
client.request(KernelRequest::GetAgentReadiness),View on GitHub (pinned to affd8760f4)
Solutions
- Restart the daemon so its protocol version matches the CLI binary
- Rebuild/reinstall astrid-cli and the daemon from the same source revision
- Check for a stale socket file from a previous daemon and remove it before restarting
- Add a protocol/version handshake to KernelRequest::Status handling to fail fast on mismatch
Example fix
// before KernelResponse::Status(_) => Ok(()), // after KernelResponse::Status(_) => Ok(()), KernelResponse::Pong => Ok(()), // accept variants a legacy daemon may return
Defensive patterns
Strategy: try-catch
Type guard
fn is_status_response(resp: &KernelResponse) -> bool { matches!(resp, KernelResponse::Status(_)) } Try / catch
match daemon_roundtrip().await {
Ok(()) => { /* healthy */ }
Err(e) if e.to_string().contains("unexpected status response") => {
// treat as version skew: advise daemon restart
}
Err(e) => eprintln!("doctor failed: {e:#}"),
} Prevention
- Restart the daemon after every CLI upgrade
- Add a protocol version handshake and check it before sending requests
- Pin CLI and daemon to the same release version in deployment scripts
When it happens
Trigger: Running `astrid doctor`'s daemon_roundtrip check while the daemon (or an intermediary protocol layer) returns an unexpected variant such as AgentReadiness or another non-Status response to a Status request, typically due to a CLI/daemon version mismatch.
Common situations: A daemon built from a different commit or older version is still running on the socket after an upgrade; a new CLI sends Status but the old daemon responds with a shape the CLI doesn't map for that request.
Related errors
- unexpected daemon metadata response: {other:?}
- Daemon returned an unexpected response to GetCommands
- daemon closed guard uplink
- unexpected daemon metadata response: {other:?}
- unexpected response from kernel: {body:?}
AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09).
Data as JSON: /api/errors/4d1ede607995f485.
Report an issue: GitHub.