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
- Fix the underlying cause shown in the per-capsule errors above (network, auth, source), then re-run `astrid init`.
- If offline, obtain a .shuttle archive and install with --offline.
- 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
- Verify network/GitHub credentials before batch installs.
- For air-gapped hosts, always use a .shuttle archive with --offline.
- Read the per-capsule error output; the lockfile is intentionally not written on total failure.
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
- Installation incomplete: {succeeded}/{total} capsule(s) inst
- --offline: capsule '{}' has a network/GitHub source '{}' — r
- unexpected response from kernel: {other:?}
- Source path does not exist: {source}
- Failed to auto-build capsule from Cargo project.
AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09).
Data as JSON: /api/errors/5009483c1a656dca.
Report an issue: GitHub.