astrid-runtime/astrid · error

failed to install {} capsule(s): {names}

Error message

failed to install {} capsule(s): {names}

What it means

`install_all_capsules` collects per-capsule failures during a batch GitHub install and, if any failed, aggregates their names into a single `bail!` message. This is a roll-up error: the individual per-capsule failures were already attempted, and the whole install command reports failure listing which capsule names failed.

Source

Thrown at crates/astrid-cli/src/commands/capsule/install.rs:552

            Err(e) => {
                eprintln!("  Failed to install {name}: {e}");
                failed.push((name, e.to_string()));
            },
        }
    }

    eprintln!(
        "Done: {} installed, {} failed.",
        installed.len(),
        failed.len()
    );
    if !failed.is_empty() {
        let names = failed
            .iter()
            .map(|(n, _)| *n)
            .collect::<Vec<_>>()
            .join(", ");
        bail!("failed to install {} capsule(s): {names}", failed.len());
    }
    Ok(installed)
}

/// Clone a GitHub repository and build the capsule from source using
/// `astrid-build`. Returns the installed capsule id.
async fn clone_and_build(
    url: &str,
    repo: &str,
    name_hint: Option<&str>,
    context: InstallContext<'_>,
) -> anyhow::Result<InstalledCapsuleOutcome> {
    let tmp_dir = tempfile::tempdir().context("failed to create temp dir for cloning")?;
    let clone_dir = tmp_dir.path().join(repo);

    let status = std::process::Command::new("git")
        .args(["clone", "--depth", "1", url, &clone_dir.to_string_lossy()])
        .status()

View on GitHub (pinned to affd8760f4)

Solutions

  1. Read the comma-separated names in the message to identify which capsules failed, then install each failing one individually to see its underlying error
  2. Fix the underlying cause per capsule (missing release asset, bad source URL, network issue)
  3. Remove or correct the failing entries in the capsule manifest/workspace configuration and re-run the batch install
  4. Re-run the install command — successfully installed capsules are tracked, so retry typically only attempts remaining work

Example fix

// before: manifest references a repo with no .capsule release asset
capsules = ["github:org/good-repo", "github:org/broken-repo"]
// after: correct or remove the failing entry
capsules = ["github:org/good-repo", "github:org/fixed-repo@v1.2.0"]
Defensive patterns

Strategy: try-catch

Validate before calling

// Pre-check each capsule source resolves before batch install
for source in capsule_sources {
    if let Err(e) = check_source_resolvable(&source) {
        eprintln!("skipping {}, unresolvable: {e}", source);
    }
}

Try / catch

match install_from_github(...) {
    Ok(installed) => println!("installed: {installed:?}"),
    Err(e) if e.to_string().contains("failed to install") => {
        // parse failed names after "failed to install N capsule(s): "
        // and retry/install each individually for per-capsule errors
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Running a multi-capsule install (e.g. `astrid capsule install` with a workspace/manifest listing several GitHub sources) where at least one capsule fails to resolve, download, or install; the failed names are joined with commas in the message.

Common situations: A workspace capsule manifest references repos whose releases lack `.capsule` assets, network/download failures on one entry, or a capsule name that doesn't exist upstream — the batch aborts after reporting all failures.

Understand the failure class

Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — this error's family across 28 libraries.

Related errors


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