{"record":{"id":"73708c02c3efbe96","repo":"astrid-runtime/astrid","slug":"daemon-kernel-request-e","errorCode":null,"errorMessage":"daemon kernel-request: {e}","messagePattern":"daemon kernel-request: (.+?)","errorType":"http","errorClass":"GatewayError::Internal","httpStatus":500,"severity":"error","filePath":"crates/astrid-gateway/src/routes/mod.rs","lineNumber":62,"sourceCode":"/// Map a bus-direct / socket kernel-request failure ([`KernelClientError`]) to a\n/// [`GatewayError`]. Single-sourced so every `kernel_client_for(...).request()`\n/// call site maps consistently.\n///\n/// A [`Timeout`](KernelClientError::Timeout) — the daemon was slow / wedged, not\n/// a transport fault — maps to **504** so callers can distinguish \"still\n/// processing, retry\" (e.g. a heavy `InstallCapsule` under load) from a genuine\n/// 500. Connection loss, bus shutdown, build, and decode failures all map to\n/// **500**. A kernel-side rejection is a `KernelResponse::Error` handled at the\n/// call site (→ 403), never reaching this path.\n#[allow(\n    clippy::needless_pass_by_value,\n    reason = \"consumed by Display formatting\"\n)]\npub(crate) fn daemon_kernel_error(e: KernelClientError) -> GatewayError {\n    if e.is_timeout() {\n        return GatewayError::Timeout(format!(\"daemon kernel-request: {e}\"));\n    }\n    GatewayError::Internal(anyhow::anyhow!(\"daemon kernel-request: {e}\"))\n}\n\npub mod agent;\npub mod audit;\npub mod auth;\npub mod caps;\n#[cfg(test)]\nmod capsule_sources;\npub mod capsules;\npub mod distribution;\npub mod env;\npub mod events;\npub mod groups;\npub mod invites;\npub mod models;\npub mod observability;\npub mod principals;\npub mod quotas;","sourceCodeStart":44,"sourceCodeEnd":80,"githubUrl":"https://github.com/astrid-runtime/astrid/blob/affd8760f44190dbdfbec23403f4c4b642c33112/crates/astrid-gateway/src/routes/mod.rs#L44-L80","documentation":"`daemon_kernel_error` is the shared mapper from `KernelClientError` to `GatewayError` used by gateway route handlers. If the kernel client error is a timeout it becomes `GatewayError::Timeout`, otherwise the whole error is wrapped as `GatewayError::Internal` with `daemon kernel-request: {e}`. It indicates the request to the daemon/kernel failed outside of normal application-level error responses.","triggerScenarios":"Any gateway route using this mapper when the kernel client call fails with a non-timeout `KernelClientError`: connection refused, channel closed, serialization failure, or daemon-side transport fault.","commonSituations":"Daemon not started before the gateway; kernel socket path misconfigured in env/config; daemon crashed mid-request; version mismatch of the kernel IPC protocol after upgrading one side only.","solutions":["Confirm the daemon/kernel process is up and the configured endpoint matches (socket path/URL).","Read the inner `{e}` in logs to classify: connection vs channel-closed vs serialization.","Align gateway and daemon versions; redeploy together after protocol changes.","For timeouts specifically, tune the kernel request timeout budget and check daemon load."],"exampleFix":"// before\nGatewayError::Internal(anyhow::anyhow!(\"daemon kernel-request: {e}\"))\n// after\nif e.is_connect() {\n    return Err(GatewayError::ServiceUnavailable(format!(\"daemon unreachable: {e}\")));\n}\nGatewayError::Internal(anyhow::anyhow!(\"daemon kernel-request: {e}\"))","handlingStrategy":"retry","validationCode":"// before issuing the request\nif !daemon_health_probe().await {\n    return Err(ServiceUnavailable(\"kernel daemon not ready\"));\n}","typeGuard":"fn is_kernel_transport_failure(e: &KernelClientError) -> bool {\n    !e.is_timeout() && (e.is_connect() || e.is_channel_closed())\n}","tryCatchPattern":"match route_call(state, req).await {\n    Err(e) if is_kernel_transport_failure(&e) => {\n        // one bounded retry after backoff\n        tokio::time::sleep(RETRY_DELAY).await;\n        route_call(state, req).await\n    }\n    r => r,\n}","preventionTips":["Start the daemon before the gateway or add startup readiness gating.","Use a bounded retry with backoff for transient kernel errors.","Validate the kernel endpoint configuration at boot and fail fast if unreachable.","Classify KernelClientError variants into distinct GatewayError types (timeout/unavailable/internal)."],"tags":["ipc","kernel","daemon","internal-error"],"backgroundTag":"internal-invariant-violation","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"}