astrid-runtime/astrid · error
source produced {} .capsule archives but no capsule name to
Error message
source produced {} .capsule archives but no capsule name to pick one; expected an archive named '<capsule>.capsule' What it means
After a GitHub source build produces .capsule archives, pick_capsule must select one. With a single archive it picks it; with several, it needs a name hint (the capsule name) to disambiguate. If multiple archives were produced and name_hint is None, it cannot choose and errors instead of guessing.
Source
Thrown at crates/astrid-capsule-install/src/github_source.rs:127
.collect()
}
/// Choose which `.capsule` to install when a source yields several. A monorepo
/// builds/releases one archive per capsule crate, named `<capsule>.capsule`, so
/// picking "the first" would install the wrong one. Returns the index into
/// `names` of the chosen archive.
///
/// * none -> `Ok(None)` (caller falls back, e.g. release -> clone+build).
/// * exactly one -> `Ok(Some(0))` — unambiguous; `name_hint` is irrelevant.
/// * several -> the one named `<name_hint>.capsule`. Without a hint, or with
/// no matching name, refuse rather than silently install the wrong capsule.
pub fn pick_capsule(names: &[&str], name_hint: Option<&str>) -> anyhow::Result<Option<usize>> {
match names {
[] => Ok(None),
[_] => Ok(Some(0)),
many => {
let Some(hint) = name_hint else {
bail!(
"source produced {} .capsule archives but no capsule name to pick one; \
expected an archive named '<capsule>.capsule'",
many.len()
);
};
// Match the hint against each candidate's stem via `strip_suffix`
// (no per-call allocation) rather than `format!`-ing the target.
match many
.iter()
.position(|n| n.strip_suffix(".capsule") == Some(hint))
{
Some(idx) => Ok(Some(idx)),
None => bail!(
"no '.capsule' archive named '{hint}.capsule' among [{}]",
many.join(", ")
),
}
},View on GitHub (pinned to affd8760f4)
Solutions
- Re-run the install with the capsule name so name_hint is Some and can disambiguate the archives (e.g. `install owner/repo <capsule-name>`).
- Delete extra .capsule artifacts from the build output so only one archive remains, or build only the target capsule.
- Rename the produced archives so exactly one follows the `<capsule>.capsule` convention and re-run.
Example fix
// before
resolve_capsule_to_file(&source, None)?;
// after
resolve_capsule_to_file(&source, Some("my-capsule"))?; Defensive patterns
Strategy: validation
Validate before calling
// caller-side check before resolving:
if capsule_names.len() > 1 && name_hint.is_none() {
return Err(anyhow::anyhow!(
"multiple .capsule archives produced ({:?}); pass the capsule name", capsule_names));
} Type guard
fn can_pick(names: &[&str], hint: Option<&str>) -> bool {
match names.len() { 0 | 1 => true, _ => hint.is_some() }
} Try / catch
match pick_capsule(&names, hint) {
Err(e) if e.to_string().contains("no capsule name to pick") => {
eprintln!("build produced {} archives; re-run with the capsule name", names.len());
}
other => other?,
} Prevention
- Always pass the capsule name when installing from multi-artifact repos.
- Keep one .capsule artifact per CI build or name artifacts `<capsule>.capsule`.
- Fail fast in scripts when name_hint would be None with multiple candidates.
When it happens
Trigger: Calling pick_capsule (via install_from_github, resolve_capsule_to_file, or clone_and_build) with names.len() > 1 and name_hint = None — i.e. the build emitted two or more .capsule files and no capsule name was supplied to match against archive stems.
Common situations: A monorepo GitHub repo whose build produces multiple .capsule artifacts while the user ran an install command without naming the capsule; a script calling resolve_capsule_to_file without passing the name; a renamed capsule so the expected `<name>.capsule` convention no longer matches the configured name.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- no '.capsule' archive named '{hint}.capsule' among [{}]
- corpus label must contain only lowercase ASCII letters, digi
- unknown migration component name: {name}
- opaque asset path must be a directory: {}
- WASM binary not found at {}
AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09).
Data as JSON: /api/errors/a99812b1df994835.
Report an issue: GitHub.