{"record":{"id":"4195890760e13460","repo":"astrid-runtime/astrid","slug":"unexpected-response-for-getagentreadiness-other","errorCode":null,"errorMessage":"unexpected response for GetAgentReadiness: {other:?}","messagePattern":"unexpected response for GetAgentReadiness: (.+?)","errorType":"http","errorClass":"GatewayError::Internal","httpStatus":500,"severity":"error","filePath":"crates/astrid-gateway/src/routes/system.rs","lineNumber":72,"sourceCode":"        (status = 200, description = \"`AgentLoopReadiness` JSON shape: `{ ready: bool, prompt_subscribers: [string], response_publishers: [string], unsatisfied_required_imports: [{ capsule, namespace, interface, requirement }], loaded_capsules: [string] }`. `ready` is false when the installed capsule set can't serve an agent chat turn.\", content_type = \"application/json\"),\n        (status = 401, body = ErrorBody),\n        (status = 403, body = ErrorBody, description = \"Caller lacks `capsule:list`.\"),\n    )\n)]\npub async fn get_readiness(\n    State(state): State<Arc<GatewayState>>,\n    req: Request<axum::body::Body>,\n) -> GatewayResult<Json<AgentLoopReadiness>> {\n    let caller = caller_from(&req)?.clone();\n    let client = state.kernel_client_for(&caller)?;\n    let resp = client\n        .request(KernelRequest::GetAgentReadiness)\n        .await\n        .map_err(daemon_kernel_error)?;\n    match resp {\n        KernelResponse::AgentReadiness(r) => Ok(Json(r)),\n        KernelResponse::Error(msg) => Err(GatewayError::Forbidden { reason: msg }),\n        other => Err(GatewayError::Internal(anyhow::anyhow!(\n            \"unexpected response for GetAgentReadiness: {other:?}\"\n        ))),\n    }\n}\n\n#[utoipa::path(\n    post,\n    path = \"/api/sys/capsules/reload\",\n    tag = \"system\",\n    responses(\n        (status = 204, description = \"Capsules reloaded.\"),\n        (status = 401, body = ErrorBody),\n        (status = 403, body = ErrorBody, description = \"Caller lacks `capsule:reload`.\"),\n    )\n)]\npub async fn reload_capsules(\n    State(state): State<Arc<GatewayState>>,\n    req: Request<axum::body::Body>,","sourceCodeStart":54,"sourceCodeEnd":90,"githubUrl":"https://github.com/astrid-runtime/astrid/blob/affd8760f44190dbdfbec23403f4c4b642c33112/crates/astrid-gateway/src/routes/system.rs#L54-L90","documentation":"The gateway asked the daemon kernel for an agent's readiness status, but the kernel replied with a KernelResponse variant that is neither AgentReadiness nor Error. This is a protocol/programming bug between the gateway and kernel, not a user input problem. The gateway converts it into a GatewayError::Internal with the offending variant debug-printed.","triggerScenarios":"get_readiness() in crates/astrid-gateway/src/routes/system.rs sends KernelRequest::GetAgentReadiness and matches only KernelResponse::AgentReadiness(r) and KernelResponse::Error(msg); any other variant (e.g. Success(_), a mismatched reply from a different request type) hits the catch-all arm.","commonSituations":"A kernel upgrade changed the response enum and the gateway was not rebuilt; requests are being routed to the wrong kernel handler; a bus reply for a different request id is delivered to this awaiting caller due to a client-side multiplexing bug.","solutions":["Check that gateway and daemon-kernel versions match and rebuild/redeploy both from the same commit","Inspect the printed {other:?} variant to identify which unexpected KernelResponse is being returned","Verify the kernel handles GetAgentReadiness and replies with KernelResponse::AgentReadiness for that request id","If reproducible, file/inspect the BusKernelClient reply-correlation logic for request/response id mismatch"],"exampleFix":"// before: mismatched versions cause stale response enum\n// after: pin both crates to the same workspace/version and rebuild\ncargo build -p astrid-gateway -p astrid-daemon-kernel","handlingStrategy":"try-catch","validationCode":"match kernel_response {\n    KernelResponse::AgentReadiness(_) | KernelResponse::Error(_) => Ok(()),\n    other => Err(format!(\"kernel version mismatch: got {other:?} for GetAgentReadiness\")),\n}","typeGuard":"fn is_agent_readiness(resp: &KernelResponse) -> bool {\n    matches!(resp, KernelResponse::AgentReadiness(_))\n}","tryCatchPattern":"match client.request(KernelRequest::GetAgentReadiness).await? {\n    KernelResponse::AgentReadiness(r) => Ok(r),\n    KernelResponse::Error(msg) => Err(GatewayError::Forbidden { reason: msg }),\n    other => { log::error!(\"kernel protocol mismatch: {other:?}\"); Err(GatewayError::Internal(anyhow::anyhow!(\"unexpected response for GetAgentReadiness: {other:?}\"))) }\n}","preventionTips":["Deploy gateway and kernel from the same build so KernelResponse enums match","Add a startup protocol/version handshake between gateway and kernel","Write an integration test asserting AgentReadiness comes back for GetAgentReadiness"],"tags":["internal","protocol-mismatch","rpc"],"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-17T15:17:12.973Z"}