astrid-runtime/astrid · error

cannot remove capsule authority while an install transaction

Error message

cannot remove capsule authority while an install transaction is pending at {}

What it means

remove_installed_authority refuses to delete the active/previous authority receipt files while a pending install transaction marker exists. The library treats the pending marker as proof an install (stage->commit) may be interrupted, so removing authority files first could leave the capsule without a recoverable authority record. It is a deliberate safety interlock against destructive cleanup during an in-flight update.

Source

Thrown at crates/astrid-capsule-install/src/authority.rs:326

    }
    #[cfg(not(unix))]
    {
        std::fs::metadata(directory)
            .with_context(|| format!("inspect authority directory {}", directory.display()))?;
    }
    Ok(())
}

/// Remove the authority state for an uninstalled capsule.
///
/// # Errors
///
/// Returns an error when an install transaction is pending or receipt cleanup
/// fails.
pub fn remove_installed_authority(home: &AstridHome, target_dir: &Path) -> anyhow::Result<()> {
    let paths = authority_paths(home, target_dir)?;
    if paths.pending.exists() {
        bail!(
            "cannot remove capsule authority while an install transaction is pending at {}",
            paths.pending.display()
        );
    }
    for path in [paths.active, paths.previous] {
        match std::fs::remove_file(&path) {
            Ok(()) => {},
            Err(error) if error.kind() == std::io::ErrorKind::NotFound => {},
            Err(error) => {
                return Err(error).with_context(|| {
                    format!("failed to remove authority receipt {}", path.display())
                });
            },
        }
    }
    Ok(())
}

View on GitHub (pinned to affd8760f4)

Solutions

  1. Inspect and finish or roll back the interrupted install transaction (call commit or resolve the pending receipt) before removing authority
  2. Verify the capsule is not currently being installed by another process, then delete the pending file at the path shown in the message and retry
  3. If the pending marker is confirmed stale, remove it manually with fs::remove_file and re-run remove_installed_authority

Example fix

// before
remove_installed_authority(&home, &target_dir)?;
// after
let pending = target_dir.join("authority").join("pending");
if pending.exists() {
    AuthorityReceiptTransaction::inspect(&home, &target_dir)?; // resolve/commit first
}
remove_installed_authority(&home, &target_dir)?;
Defensive patterns

Strategy: validation

Validate before calling

let pending = authority_pending_path(&home, &target_dir);
if pending.exists() {
    return Err(anyhow!("resolve pending install transaction at {} first", pending.display()));
}

Prevention

When it happens

Trigger: Calling remove_installed_authority(home, target_dir) when the authority_paths(home, target_dir)?.pending file exists — i.e. AuthorityReceiptTransaction::stage was run but commit/receipt cleanup did not finish.

Common situations: A previous capsule install or update was interrupted (crash, kill, power loss) leaving the pending marker; automated cleanup scripts run concurrently with an in-progress install; stale pending files after a failed commit.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09). Data as JSON: /api/errors/5b98c38fe5877576. Report an issue: GitHub.