astrid-runtime/astrid · error
no '.capsule' archive named '{hint}.capsule' among [{}]
Error message
no '.capsule' archive named '{hint}.capsule' among [{}] What it means
pick_capsule was given a name hint, but none of the candidate archive names has `<hint>.capsule` as its exact suffix (compared by stripping ".capsule" and matching the stem). It reports the hint and the full candidate list so the caller can correct the name or see what was actually built.
Source
Thrown at crates/astrid-capsule-install/src/github_source.rs:140
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(", ")
),
}
},
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_strip_version_prefix() {
assert_eq!(strip_version_prefix("v1.2.3"), "1.2.3");
assert_eq!(strip_version_prefix("V1.0.0"), "1.0.0");
assert_eq!(strip_version_prefix("1.0.0"), "1.0.0");
assert_eq!(strip_version_prefix("v0.0.1-alpha"), "0.0.1-alpha");View on GitHub (pinned to affd8760f4)
Solutions
- Compare the hint against the archive list in the message and re-run with the exact archive stem (e.g. my-capsule not My-Capsule).
- Fix the build/CI so the produced archive is named `<capsule>.capsule` exactly (strip version suffixes from the artifact name).
- Pass None if there is truly only one archive, or trim the candidate list to one so no hint is needed.
Example fix
// before
pick_capsule(&["my-capsule-1.2.0"], Some("my-capsule"))
// after
pick_capsule(&["my-capsule-1.2.0"], Some("my-capsule-1.2.0")) // or emit my-capsule.capsule Defensive patterns
Strategy: validation
Validate before calling
// verify the hint matches a candidate before calling:
let ok = names.iter().any(|n| n.strip_suffix(".capsule") == Some(hint));
assert!(ok, "no archive named {hint}.capsule among {names:?}"); Try / catch
match pick_capsule(&names, Some(hint)) {
Err(e) if e.to_string().contains("among [") => {
eprintln!("hint {:?} not found; candidates: {:?}", hint, names);
}
other => other?,
} Prevention
- Derive the hint from the capsule manifest name, not a hardcoded string.
- Name build artifacts exactly `<capsule>.capsule` without version suffixes.
- Watch for case mismatches; compare stems case-sensitively.
When it happens
Trigger: Calling pick_capsule with name_hint = Some(h) where h does not equal any candidate's stem: the build produced archives with different names (different or renamed capsule, versioned filenames like my-capsule-1.2.0.capsule, wrong casing) than the supplied hint.
Common situations: Capsule renamed in its manifest after the install command/alias was written; a build producing version-suffixed archive names; typos in the capsule name; case mismatch on case-sensitive filesystems.
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
- source produced {} .capsule archives but no capsule name to
- 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/e3a3035d38f5f0b4.
Report an issue: GitHub.