astrid-runtime/astrid · error
daemon rejected capsule removal
Error message
daemon rejected capsule removal: {message} What it means
`dispatch_capsule_remove` sends a removal request to the astrid daemon and expects a success response. When the daemon replies with `KernelResponse::Error(message)`, the CLI surfaces the daemon's rejection message wrapped in this bail instead of proceeding to print "Removed".
Solutions
- Read the daemon's message after the colon — it states the actual rejection reason — and address it (fix the capsule name, stop the capsule, etc.).
- Verify the capsule exists and is stopped with a list/status command before removing.
- Restart the daemon if the capsule is in a stuck state, then retry the removal.
Example fix
// before: removing a running/unknown capsule fails astrid capsule remove my-capsule // after: check state first, stop, then remove astrid capsule list astrid capsule stop my-capsule astrid capsule remove my-capsule
Defensive patterns
Strategy: try-catch
Validate before calling
// before removing, confirm the capsule exists and is stopped
let status = daemon_client.status(capsule_name)?;
if !status.exists { return Err(format!("capsule '{capsule_name}' not found").into()); }
if status.running { return Err(format!("stop capsule '{capsule_name}' before removing").into()); } Type guard
fn is_kernel_success(resp: &astrid_core::kernel_api::KernelResponse) -> bool {
!matches!(resp, astrid_core::kernel_api::KernelResponse::Error(_))
} Try / catch
match dispatch_capsule_remove(name) {
Err(e) if e.to_string().starts_with("daemon rejected capsule removal") => {
let reason = e.to_string().splitn(2, ": ").nth(1).unwrap_or("unknown");
eprintln!("removal rejected by daemon: {reason}");
}
other => other?,
} Prevention
- Verify the exact capsule name with a list command before removal.
- Stop running capsules before attempting removal.
- Inspect and act on the daemon's rejection message rather than retrying blindly.
When it happens
Trigger: Running a capsule remove command when the daemon cannot perform the removal — e.g. the capsule does not exist, is currently running, or the daemon's kernel refuses the operation — and responds with an Error variant.
Common situations: Removing a typo'd or already-deleted capsule name; attempting to remove a capsule with running processes or open references; daemon-side permission or state problems.
Related errors
- an Astrid daemon appears to be running but its uplink is…
- Capsule ' ' is not installed.
- Capsule ' ' is not installed.
- capsules are installed, but connecting to the selected…
- Daemon exited prematurely
AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09).
Data as JSON: /api/errors/c93194f32c09cddf.
Report an issue: GitHub.
Appendix: source
Thrown at crates/astrid-cli/src/dispatch.rs:467
.await?
{
astrid_core::kernel_api::KernelResponse::Success(_) => {
if purge {
let principal = crate::principal::current();
let entries =
commands::capsule::install_headless::list_env_entries(&principal, &name)?;
for entry in entries {
if matches!(entry.scope, astrid_core::kernel_api::EnvStorageScope::Agent) {
commands::capsule::install_headless::delete_env_entry(
&principal, &name, &entry.key, entry.kind,
)?;
}
}
}
eprintln!("Removed '{name}'.");
},
astrid_core::kernel_api::KernelResponse::Error(message) => {
anyhow::bail!("daemon rejected capsule removal: {message}");
},
other => anyhow::bail!("unexpected daemon response: {other:?}"),
}
Ok(ExitCode::SUCCESS)
}
async fn dispatch_mcp(command: McpCommands) -> Result<ExitCode> {
if !matches!(command, McpCommands::Gc) {
commands::daemon::validate_runtime_admission()?;
}
match command {
McpCommands::Serve {
workspace,
request_timeout: _,
} => commands::mcp::serve(None, workspace.as_deref()).await,
McpCommands::Attach { workspace } => {
commands::mcp::attach(None, workspace.as_deref()).await
},View on GitHub (pinned to affd8760f4)