astrid-runtime/astrid · error

all {total} capsule install(s) failed — not writing Distro.l

Error message

all {total} capsule install(s) failed — not writing Distro.lock. Fix the errors above and re-run `astrid init`.

What it means

reject_total_install_failure aborts init when every requested capsule install failed (total > 0, succeeded == 0). In that case Distro.lock is intentionally not written, since locking a distro where nothing installed would be misleading; the user must fix the errors and retry.

Source

Thrown at crates/astrid-cli/src/commands/init.rs:578

}

/// Whether a provision run should persist a `Distro.lock`.
///
/// Only a FULL success (`succeeded == total`) or an empty selection
/// (`total == 0`, nothing to install) writes a lock. A PARTIAL run writes
/// NO lock. This keeps the outcome honest and ensures a retry still evaluates
/// every member through the durable identity query instead of trusting a
/// partial record. Because `install_capsule_batch` is idempotent, withholding
/// the lock lets a re-run re-attempt missing capsules and converge to a full
/// success, which then writes the lock.
/// A wholly-failed run also writes no lock (and additionally bails non-zero).
fn should_write_lock(total: usize, succeeded: usize) -> bool {
    total == 0 || succeeded == total
}

fn reject_total_install_failure(total: usize, succeeded: usize) -> anyhow::Result<()> {
    if total > 0 && succeeded == 0 {
        bail!(
            "all {total} capsule install(s) failed — not writing Distro.lock. \
             Fix the errors above and re-run `astrid init`."
        );
    }
    Ok(())
}

/// Persist `lock` at `lock_path` iff the run earned it (see
/// [`should_write_lock`]). Returns whether the lock was written, so the
/// caller can pick the honest completion message. Kept as a small helper so
/// the "partial run leaves no lock on disk" invariant is unit-testable
/// without a network install.
#[cfg(test)]
fn persist_lock_if_earned(
    lock_path: &std::path::Path,
    total: usize,
    succeeded: usize,
    lock: &DistroLock,

View on GitHub (pinned to affd8760f4)

Solutions

  1. Fix the underlying cause shown in the per-capsule errors above (network, auth, source), then re-run `astrid init`.
  2. If offline, obtain a .shuttle archive and install with --offline.
  3. Verify the distro's capsule sources are reachable (git ls-remote / curl the raw URLs) before retrying.
Defensive patterns

Strategy: retry

Validate before calling

if !Command::new("curl").args(["-sI", "https://raw.githubusercontent.com"]).status()?.success() {
    eprintln!("no network; use a .shuttle archive with --offline");
}

Try / catch

let status = Command::new("astrid").args(["init"]).status()?;
if !status.success() {
    eprintln!("install failed entirely; fix errors then rerun");
}

Prevention

When it happens

Trigger: install flow reaches reject_total_install_failure with succeeded == 0 and total > 0 — e.g. all capsule installs failed due to network outage, bad distro manifest, or revoked source access.

Common situations: No network connectivity when the distro requires GitHub sources; GitHub auth expired/revoked for all private capsule repos; corrupt or wrong-version distro manifest.

Related errors


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