astrid-runtime/astrid · error
durable capsule {id} is missing WIT file {relative}
Error message
durable capsule {id} is missing WIT file {relative} What it means
verify_wit_files looks up each WIT file listed in the capsule metadata under the `wit/` key in the archive's in-memory file map. If the archive does not contain the file the metadata pins, the package is internally inconsistent — metadata and archive disagree — and reading the durable package fails rather than silently missing an interface definition.
Source
Thrown at crates/astrid-capsule-install/src/storage.rs:225
let mut expected = std::collections::BTreeSet::new();
for (relative, pin) in &metadata.wit_files {
let relative_path = Path::new(relative);
if relative_path.is_absolute()
|| relative_path.components().any(|component| {
matches!(
component,
std::path::Component::ParentDir | std::path::Component::RootDir
)
})
|| relative_path
.components()
.any(|component| !matches!(component, std::path::Component::Normal(_)))
{
bail!("durable capsule {id} has unsafe WIT metadata path {relative}");
}
let key = format!("wit/{relative}");
let Some(bytes) = files.get(&key) else {
bail!("durable capsule {id} is missing WIT file {relative}");
};
if !is_hex_digest(pin) || blake3::hash(bytes).to_hex().as_str() != pin {
bail!("durable capsule {id} WIT digest mismatch for {relative}");
}
expected.insert(key);
}
for key in files.keys().filter(|key| key.starts_with("wit/")) {
if Path::new(key)
.extension()
.is_some_and(|extension| extension.eq_ignore_ascii_case("wit"))
&& !expected.contains(key)
{
bail!("durable capsule {id} has an unpinned WIT file {key}");
}
}
Ok(())
}
View on GitHub (pinned to affd8760f4)
Solutions
- Re-add the missing .wit file to the capsule source and republish/reinstall the capsule.
- Regenerate metadata so wit_files matches the actual archive contents (rebuild the capsule package).
- If the archive was truncated in transit, re-download/reinstall from the registry.
- Verify consistency locally before publishing by digesting the built archive.
Example fix
// before: metadata pins types.wit but archive lacks it
// metadata.wit_files = {"types.wit": pin}; archive has only wit/api.wit
// after: restore or republish so both sides agree
cp types.wit wit/ && republish capsule Defensive patterns
Strategy: validation
Validate before calling
fn all_pinned_wits_present(metadata_wit_files: &[(String, String)], archive_files: &[String]) -> bool {
metadata_wit_files.iter().all(|(rel, _)| archive_files.iter().any(|f| f == &format!("wit/{rel}")))
} Type guard
fn wit_file_in_archive(rel: &str, files: &std::collections::BTreeMap<String, Vec<u8>>) -> bool {
files.contains_key(&format!("wit/{rel}"))
} Try / catch
match read_verified_durable_package_for_owner(id) {
Err(e) if e.to_string().contains("is missing WIT file") => {
// metadata/archive disagreement: republish or reinstall the capsule
reinstall_capsule(id)?;
}
other => other?,
} Prevention
- Regenerate metadata whenever WIT files are added, renamed, or removed
- Never edit archive contents or metadata independently
- Verify archives fully downloaded/transferred before installing
- Digest the built archive locally before publishing to catch missing files
When it happens
Trigger: read_verified_durable_package_for_owner on a capsule where metadata.wit_files declares a relative path whose corresponding `wit/<relative>` entry is absent from the archive files — e.g. the WIT file was deleted or renamed after metadata was generated, or the archive was rebuilt without it.
Common situations: Renaming/removing a .wit file without republishing; partial archive upload/truncation dropping files; editing the durable store to update one side only; version drift between metadata and archive.
Understand the failure class
Background: Record Not Found Errors: "not found", RecordNotFound, and "was not found" — what they mean and how to fix them — this error's family across 28 libraries.
Related errors
- durable capsule {id} has an unpinned WIT file {key}
- durable capsule {} is missing its pinned contracts blob
- durable capsule {id} WIT digest mismatch for {relative}
- durable capsule {id} imports differ between metadata and arc
- opaque capsule asset directories cannot be symlinks: {}
AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09).
Data as JSON: /api/errors/32541379233f14ba.
Report an issue: GitHub.