{"record":{"id":"31c8484c09737eed","repo":"astrid-runtime/astrid","slug":"daemon-error-err","errorCode":null,"errorMessage":"Daemon error: {err}","messagePattern":"Daemon error: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/astrid-cli/src/commands/capsule_verb.rs","lineNumber":198,"sourceCode":"    let msg = astrid_types::ipc::IpcMessage::new(\n        astrid_types::Topic::kernel_request(\"get_commands\"),\n        astrid_types::ipc::IpcPayload::RawJson(val),\n        source_id,\n    )\n    .with_principal(caller.to_string());\n    client.send_message(msg).await?;\n    let raw = client\n        .read_until_topic(\n            astrid_types::Topic::kernel_response(\"get_commands\").as_str(),\n            Duration::from_secs(10),\n        )\n        .await?;\n    match SocketClient::extract_kernel_response(&raw) {\n        Some(astrid_core::kernel_api::KernelResponse::Commands(cmds)) => Ok(cmds),\n        // Surface the daemon's own error (e.g. a capability/permission denial)\n        // instead of folding it into a generic \"unexpected response\".\n        Some(astrid_core::kernel_api::KernelResponse::Error(err)) => {\n            anyhow::bail!(\"Daemon error: {err}\")\n        },\n        _ => anyhow::bail!(\"Daemon returned an unexpected response to GetCommands\"),\n    }\n}\n\n/// Publish the run request and await + render the result.\nasync fn execute(provider: &str, verb: &str, args: &[String]) -> Result<ExitCode> {\n    let session = astrid_core::SessionId::from_uuid(Uuid::new_v4());\n    let source_id = session.0;\n    // Bind the connection to the active principal so the capsule verb runs\n    // under the invoking identity's context (VFS/KV/secrets), not the\n    // `default` (admin) principal a nil/unstamped message falls back to.\n    let caller = crate::principal::current();\n    let mut client =\n        match crate::socket_client::connect_for_workspace(session, caller.clone(), None).await {\n            Ok(c) => c,\n            Err(e) => {\n                eprintln!(","sourceCodeStart":180,"sourceCodeEnd":216,"githubUrl":"https://github.com/astrid-runtime/astrid/blob/affd8760f44190dbdfbec23403f4c4b642c33112/crates/astrid-cli/src/commands/capsule_verb.rs#L180-L216","documentation":"resolve_commands asks the daemon for its external command list (GetCommands). When the daemon replies with KernelResponse::Error(err), the CLI deliberately surfaces the daemon's own error message as 'Daemon error: {err}' instead of folding it into a generic unexpected-response error. Per the source comment this typically represents a capability or permission denial on the daemon side.","triggerScenarios":"Invoking a command that must resolve its verb list via the daemon (external capsule verbs) while the daemon denies GetCommands — e.g. the caller lacks the required capability, or the daemon rejects the session/workspace context.","commonSituations":"Running external capsule verbs without the daemon permission configured for your principal; daemon policy changes after an upgrade; expired or unauthenticated daemon session.","solutions":["Read the embedded daemon reason and grant the required capability/permission for the caller in the daemon policy.","Re-authenticate the session with the daemon and retry.","Restart the daemon if its policy state is stale after an upgrade."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// probe capabilities before resolving external verbs\nlet caps = client.request(KernelRequest::GetCapabilities).await?;\nif !caps.allows_external_verbs() {\n    eprintln!(\"principal lacks capability for external capsule verbs\");\n}","typeGuard":"fn is_daemon_denial(e: &anyhow::Error) -> bool {\n    e.to_string().starts_with(\"Daemon error:\")\n}","tryCatchPattern":"match resolve_commands(...).await {\n    Err(e) if is_daemon_denial(&e) => {\n        // read the daemon reason; request the capability or re-authenticate\n    }\n    r => r,\n}","preventionTips":["Configure required capabilities for principals that resolve external verbs.","Re-authenticate daemon sessions after policy changes.","Keep daemon policy changes versioned with your deployment."],"tags":["ipc","daemon","permissions"],"backgroundTag":"api-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"}