{"record":{"id":"3e840515abc91243","repo":"astrid-runtime/astrid","slug":"kernel-rejected-request-msg-3e8405","errorCode":null,"errorMessage":"kernel rejected request: {msg}","messagePattern":"kernel rejected request: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/astrid-uplink/src/kernel_client.rs","lineNumber":470,"sourceCode":"    #[cfg(all(test, unix))]\n    fn from_socket_for_test(inner: SocketClient, caller: PrincipalId, timeout: Duration) -> Self {\n        Self {\n            inner,\n            caller,\n            timeout,\n            device_key_id: None,\n        }\n    }\n}\n\n/// Convenience: lift a [`KernelResponse::Error`] into `Err`.\n///\n/// # Errors\n/// Returns an error wrapping the kernel's error message when the\n/// response is `KernelResponse::Error`.\npub fn into_result(resp: KernelResponse) -> Result<KernelResponse> {\n    match resp {\n        KernelResponse::Error(msg) => Err(anyhow!(\"kernel rejected request: {msg}\")),\n        other => Ok(other),\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n\n    #[test]\n    fn topic_suffixes_match_cli_conventions() {\n        // Pin these to the strings the CLI's existing kernel-request\n        // code already uses (who.rs, daemon.rs, ps.rs, doctor.rs).\n        // Drift here means the gateway and CLI publish to different\n        // topics for the same payload — silent breakage.\n        assert_eq!(topic_suffix(&KernelRequest::GetStatus), \"status\");\n        assert_eq!(topic_suffix(&KernelRequest::ListCapsules), \"list_capsules\");\n        assert_eq!(topic_suffix(&KernelRequest::GetCommands), \"get_commands\");\n        assert_eq!(topic_suffix(&KernelRequest::GetCapsuleMetadata), \"metadata\");","sourceCodeStart":452,"sourceCodeEnd":488,"githubUrl":"https://github.com/astrid-runtime/astrid/blob/affd8760f44190dbdfbec23403f4c4b642c33112/crates/astrid-uplink/src/kernel_client.rs#L452-L488","documentation":"Raised by the public helper `into_result` in `astrid-uplink/src/kernel_client.rs:470`, which converts a `KernelResponse` into a `Result`: the `KernelResponse::Error(msg)` variant becomes an `anyhow` error carrying the kernel's message. This is the generic kernel-plane counterpart to the admin_client conversion and is the point where server-side rejections surface as `Err` to all `request()`-style callers.","triggerScenarios":"Specifically: calling `into_result(resp)` where `resp` is `KernelResponse::Error(msg)`. Any kernel request (via `KernelClient::request` or `request_with_ceiling`) that the kernel answers with an error frame — bad arguments, unknown projection, denied operation, internal kernel error — produces this.","commonSituations":"Requesting an operation against a kernel that doesn't support it (version skew); malformed request payloads rejected by kernel validation; operating on entities that don't exist on the kernel; permission or session-state problems; kernel under load returning explicit failures.","solutions":["Read the embedded `{msg}` for the kernel's concrete reason and correct the request accordingly.","Match client and kernel versions; re-run after aligning the deployment.","Validate entity names/payload shape client-side before sending (e.g. check the projection exists).","Check session/token state if the message indicates authorization failure, then reconnect and re-authenticate.","Avoid blanket retries — treat this as a deterministic rejection unless the message indicates a transient kernel condition."],"exampleFix":"// before\nlet resp = client.request(message).await?;\n// after\nlet resp = client.request(message).await?;\nlet resp = kernel_client::into_result(resp).map_err(|e| {\n    warn!(error = %e, \"kernel rejected request\");\n    e\n})?;","handlingStrategy":"try-catch","validationCode":"// Pre-validate the request payload against the kernel schema before send\nserde_json::to_value(&request).context(\"request must serialize to the kernel schema\")?;","typeGuard":"fn kernel_err(resp: &KernelResponse) -> Option<&str> {\n    match resp {\n        KernelResponse::Error(msg) => Some(msg),\n        _ => None,\n    }\n}","tryCatchPattern":"let resp = kernel_client::into_result(client.request(message).await?)\n    .map_err(|e| anyhow!(\"kernel call failed: {e:#}\"))?;","preventionTips":["Always route kernel replies through `into_result` rather than matching Success manually.","Validate entity names and payload shape before sending requests.","Keep client/kernel versions synchronized.","Differentiate deterministic rejections from transient failures before deciding to retry."],"tags":["kernel","ipc","rpc","protocol"],"backgroundTag":"http-error-response","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"}