astrid-runtime/astrid · error
capsule ' ' is missing from the shuttle mirror
Error message
capsule '{}' is missing from the shuttle mirror What it means
verify_capsule_hashes iterates the capsules recorded in DistroLock and resolves each to its mirror file. If a locked capsule's archive is absent from the shuttle mirror, the integrity gate bails before any install side effects (the function is deliberately pure). Unlike error 290 this checks the full lock, not just the user's selection.
Solutions
- Rebuild the shuttle so the mirror contains every capsule named in DistroLock
- Verify the mirror directory contents against the lock's capsule list before transport
- Re-copy the shuttle if media loss is suspected
Example fix
// before // ls /media/shuttle/capsules -> distro-core.capsule missing // after // astrid distro pack --output /media/shuttle # repopulate mirror to match lock
Defensive patterns
Strategy: validation
Validate before calling
for entry in &lock.capsules {
let file = shuttle::capsule_mirror_path(mirror, &entry.name);
if !file.is_file() {
return Err(anyhow!("capsule '{}' missing from mirror", entry.name));
}
} Prevention
- Run a mirror-vs-lock completeness check before shipping the shuttle
- Copy media with verification (checksum-aware copy tools)
- Monitor for disk-full during shuttle packing
When it happens
Trigger: install_from_shuttle where the lock lists a capsule whose archive file is missing from the mirror directory — shuttle built incompletely, file deleted, or lock from a newer build than the mirror.
Common situations: Shuttle media partially copied; capsules dropped during packing due to disk-full; lock regenerated while the mirror directory wasn't repopulated.
Understand the failure class
Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.
Related errors
- capsule ' ' is not present in the shuttle (offline install…
- manifest hash mismatch: lock records
- BLAKE3 evidence collision with inconsistent file lengths
- BLAKE3 evidence collision with inconsistent lengths
- capsule archive contains duplicate entry
AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09).
Data as JSON: /api/errors/f82a895bf24fcba4.
Report an issue: GitHub.
Appendix: source
Thrown at crates/astrid-cli/src/commands/distro/shuttle_install.rs:302
},
None if signed => bail!(
"signed shuttle for '{distro_id}' is missing its manifest_hash binding — refusing. \
The signature covers the lock, not Distro.toml; without manifest_hash the manifest \
(env/selection) is unauthenticated and could be swapped."
),
None => Ok(()),
}
}
/// Verify the per-capsule blake3 of every lock entry against the bytes
/// actually present in the mirror. Returns an error on the first
/// mismatch or missing file. Pure (no install side effects) so the
/// integrity gate is unit-testable.
fn verify_capsule_hashes(mirror: &Path, lock: &DistroLock) -> anyhow::Result<()> {
for entry in &lock.capsules {
let file = shuttle::capsule_mirror_path(mirror, &entry.name);
if !file.is_file() {
bail!(
"capsule '{}' is missing from the shuttle mirror",
entry.name
);
}
let bytes = std::fs::read(&file)
.with_context(|| format!("failed to read mirrored capsule {}", entry.name))?;
let actual = format!("blake3:{}", blake3::hash(&bytes).to_hex());
if entry.hash != actual {
bail!(
"capsule '{}' hash mismatch: lock has {}, archive has {actual}",
entry.name,
entry.hash
);
}
}
Ok(())
}
View on GitHub (pinned to affd8760f4)