astrid-runtime/astrid · error
principal capsule removal must go through the authenticated
Error message
principal capsule removal must go through the authenticated daemon
What it means
remove_capsule refuses to remove a capsule that is not scoped to the workspace: only workspace capsules may be removed directly by the CLI. Principal (user-level) capsules are managed by the authenticated daemon, so the CLI blocks local removal to avoid bypassing daemon-side authentication and state. This is an intentional guard, not a failure of the removal itself.
Source
Thrown at crates/astrid-cli/src/commands/capsule/remove.rs:30
use astrid_core::PrincipalId;
use astrid_core::dirs::AstridHome;
use super::meta::CapsuleMeta;
/// Remove an installed capsule by name.
///
/// The caller must run [`validate_capsule_removal`] before any live unload and
/// this on-disk deletion. Keeping deletion validation-free avoids a second
/// dependency scan after daemon unload and prevents a stale second snapshot
/// from disagreeing with the already-authorized operation.
pub(crate) fn remove_capsule(
name: &str,
workspace: bool,
force: bool,
purge: bool,
) -> anyhow::Result<()> {
if !workspace {
bail!("principal capsule removal must go through the authenticated daemon");
}
let home = AstridHome::resolve()?;
let principal = crate::principal::current();
remove_capsule_from_home_for(&home, &principal, name, workspace, force, purge)
}
fn remove_capsule_from_home(
home: &AstridHome,
name: &str,
workspace: bool,
force: bool,
purge: bool,
) -> anyhow::Result<()> {
let principal = astrid_capsule_install::paths::install_principal();
remove_capsule_from_home_for(home, &principal, name, workspace, force, purge)
}
fn remove_capsule_from_home_for(View on GitHub (pinned to affd8760f4)
Solutions
- If the capsule lives in the current workspace, re-run with the workspace flag: astrid capsule remove <name> --workspace.
- For principal capsules, perform the removal through the authenticated daemon path (daemon-managed remove command) instead of the CLI-local path.
- Verify with capsule list which scope the capsule belongs to before removing.
Example fix
// before remove_capsule(name, false, force, purge).await? // after remove_capsule(name, true, force, purge).await? // workspace-scoped removal
Defensive patterns
Strategy: validation
Validate before calling
// pick the right removal path up front
let is_workspace_capsule = workspace_root.join("capsules").join(name).exists();
if !is_workspace_capsule {
eprintln!("principal capsule: route removal through the authenticated daemon");
} Type guard
fn requires_daemon_removal(workspace: bool) -> bool { !workspace } Try / catch
if let Err(e) = remove_capsule(...).await {
if e.to_string().contains("authenticated daemon") {
// switch to the daemon-managed removal command
} else { return Err(e); }
} Prevention
- Always pass --workspace for workspace-scoped capsules.
- Check capsule list scope before removal.
- Script daemon-scope removals via the authenticated daemon API, not the local path.
When it happens
Trigger: Calling capsule remove without the workspace flag (workspace == false), so the code takes the principal-capsule path and bails immediately.
Common situations: Users omitting --workspace when the capsule they see is actually a workspace capsule registered differently; scripting removals against principal capsules; migration from older CLIs that allowed local principal removal.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- unexpected env list response: {response:?}
- daemon rejected capsule metadata request: {message}
- Daemon error: {err}
- Daemon returned an unexpected response to GetCommands
- Daemon exited prematurely ({status}).{}
AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09).
Data as JSON: /api/errors/2c8efa690dacf3b5.
Report an issue: GitHub.