{"record":{"id":"5ea0522f93a9ea55","repo":"astrid-runtime/astrid","slug":"running-daemon-declined-live-capsule-unload-reas","errorCode":null,"errorMessage":"running daemon declined live capsule unload: {reason}","messagePattern":"running daemon declined live capsule unload: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/astrid-cli/src/commands/capsule/live_load.rs","lineNumber":170,"sourceCode":"        .await\n        .context(\"failed to send live capsule unload request\")?;\n\n    let raw = client\n        .read_until_topic(response_topic.as_str(), std::time::Duration::from_secs(15))\n        .await\n        .context(\"running daemon did not confirm live capsule unload\")?;\n\n    match crate::socket_client::SocketClient::extract_kernel_response(&raw) {\n        Some(KernelResponse::Success(data)) => {\n            match data.get(\"status\").and_then(serde_json::Value::as_str) {\n                Some(\"unloaded\") => Ok(LiveUnload::Unloaded),\n                Some(\"not_loaded\") => Ok(LiveUnload::NotLoaded),\n                Some(other) => bail!(\"running daemon returned unknown unload status {other:?}\"),\n                None => bail!(\"running daemon returned unload success without a status\"),\n            }\n        },\n        Some(KernelResponse::Error(reason)) => {\n            bail!(\"running daemon declined live capsule unload: {reason}\")\n        },\n        _ => bail!(\"running daemon returned a malformed live capsule unload response\"),\n    }\n}\n\nasync fn daemon_socket_reachable() -> bool {\n    let path = crate::socket_client::proxy_socket_path();\n    matches!(\n        astrid_core::local_transport::connect_outcome(&path).await,\n        Ok(astrid_core::local_transport::ConnectOutcome::Connected(_))\n    )\n}\n\nfn classify_live_client<T>(\n    result: crate::socket_client::WorkspaceConnectionResult<T>,\n) -> anyhow::Result<Option<T>> {\n    match result {\n        Ok(client) => Ok(Some(client)),","sourceCodeStart":152,"sourceCodeEnd":188,"githubUrl":"https://github.com/astrid-runtime/astrid/blob/affd8760f44190dbdfbec23403f4c4b642c33112/crates/astrid-cli/src/commands/capsule/live_load.rs#L152-L188","documentation":"try_daemon_unload throws this when the running daemon explicitly responds with a KernelResponse::Error, carrying the daemon's reason for refusing the unload. The CLI surfaces that reason verbatim so the operator sees the daemon's actual denial (e.g. capability or permission failure) instead of a generic failure. This is a deliberate daemon-side rejection, not a transport or parse problem.","triggerScenarios":"Sending KernelRequest::UnloadCapsule to a live daemon that responds KernelResponse::Error(reason) — for instance the daemon refuses because the capsule is busy, another session holds it, or the requester lacks permission.","commonSituations":"Unloading a capsule that is actively in use by a running agent; the daemon's policy denies unload for privileged capsules; stale daemon state references a capsule locked by a crashed session.","solutions":["Read the daemon's reason embedded in the message and address it (e.g. stop the agent using the capsule before unloading).","Restart the daemon if the refusal is caused by stale locks or sessions holding the capsule.","Use --force-style removal paths or perform an offline uninstall if the daemon persistently refuses."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// check daemon reachability and session permissions before unload\nassert!(daemon_socket_reachable().await, \"daemon not reachable\");","typeGuard":"fn is_daemon_denial(e: &anyhow::Error) -> bool {\n    e.to_string().contains(\"declined live capsule unload\")\n}","tryCatchPattern":"if let Err(e) = try_daemon_unload(...).await {\n    if is_daemon_denial(&e) {\n        // inspect daemon reason, stop dependent agents, retry once\n    } else { return Err(e); }\n}","preventionTips":["Stop agents using the capsule before issuing a live unload.","Confirm the requesting principal has unload permission in daemon policy.","Check for other sessions holding the capsule before unloading."],"tags":["ipc","daemon","permission"],"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-17T15:17:12.973Z"}