astrid-runtime/astrid · error
durable capsule {id} imports differ between metadata and arc
Error message
durable capsule {id} imports differ between metadata and archive What it means
This error fires when the imports list in the durable metadata (CapsuleMeta.imports) differs from the import list computed from the archive manifest (version_map_to_strings over manifest.imports). Metadata and archive must describe the same WIT import surface; a discrepancy means the metadata was written for a different archive revision or the manifest's imports changed without regenerating metadata. The library refuses to load such a capsule since its recorded interface is unreliable.
Source
Thrown at crates/astrid-capsule-install/src/storage.rs:283
}
if authority.capsule_id != id || manifest.package.name != id {
bail!("durable capsule {id} identity differs across archive and authority");
}
if authority.version != manifest.package.version || metadata.version != authority.version {
bail!("durable capsule {id} version differs across package records");
}
let manifest_digest = crate::authority::digest_manifest(manifest_bytes);
if authority.manifest_digest != manifest_digest {
bail!("durable capsule {id} manifest digest differs from authority receipt");
}
if authority.content_digest != verification.content_digest() {
bail!("durable capsule {id} content digest differs from authority receipt");
}
let expected_imports = crate::wit::version_map_to_strings(&manifest.imports, |definition| {
definition.version.to_string()
});
if metadata.imports != expected_imports {
bail!("durable capsule {id} imports differ between metadata and archive");
}
let expected_exports = crate::wit::version_map_to_strings(&manifest.exports, |definition| {
definition.version.to_string()
});
if metadata.exports != expected_exports {
bail!("durable capsule {id} exports differ between metadata and archive");
}
if authority.wasm_hash_pinned && metadata.wasm_hash != authority.approved_wasm_hash {
bail!("durable capsule {id} metadata executable hash differs from authority receipt");
}
if let Some(component) = manifest.components.first() {
let Some(relative) = component.path.to_str() else {
bail!("durable capsule {id} component path is not UTF-8");
};
let Some(bytes) = archive_files.get(relative) else {
bail!("durable capsule {id} component is missing from its archive");
};
if Path::new(relative)View on GitHub (pinned to affd8760f4)
Solutions
- Regenerate the durable metadata from the current archive so metadata.imports matches manifest.imports.
- Reinstall the capsule from a single consistent published archive + metadata set.
- If the imports change is intentional, republish the capsule (new version) and reinstall so all records update together.
- Restore both metadata and archive from the same backup snapshot, not mixed sources.
Example fix
// before: metadata generated from old manifest // metadata.imports = ["wasi:io/streams@0.2.0"], manifest now also imports wasi:clocks // after: regenerate metadata from the archive let meta = CapsuleMeta::from_manifest(&manifest)?; // recomputes imports/exports store.write_metadata(owner, id, &meta)?;
Defensive patterns
Strategy: validation
Validate before calling
let expected: Vec<String> = crate::wit::version_map_to_strings(&manifest.imports, |d| d.version.to_string());
if metadata.imports != expected {
// regenerate metadata from the archive before loading
} Type guard
fn imports_match(meta: &CapsuleMeta, manifest: &CapsuleManifest) -> bool {
meta.imports == crate::wit::version_map_to_strings(&manifest.imports, |d| d.version.to_string())
} Try / catch
match store.read_verified_durable_package_for_owner(owner, id) {
Ok(pkg) => pkg,
Err(e) if e.to_string().contains("imports differ between metadata and archive") => {
let meta = CapsuleMeta::from_manifest(&manifest)?;
store.write_metadata(owner, id, &meta)?;
store.read_verified_durable_package_for_owner(owner, id)?
}
Err(e) => return Err(e),
} Prevention
- Always regenerate durable metadata whenever the manifest's WIT imports/exports change.
- Publish new versions for interface changes rather than patching installed capsules.
- Restore metadata and archive from the same snapshot, never from different revisions.
- Diff metadata.imports against the manifest in CI before shipping an archive.
When it happens
Trigger: read_verified_durable_package_for_owner computes expected imports from the archive manifest and finds CapsuleMeta.imports != expected — e.g. adding/removing a WIT import in the manifest after the durable metadata was generated, or restoring metadata and archive from different capsule versions.
Common situations: Adding a new world import dependency and rebuilding only the archive; partial restore from backup mixing metadata of v1 with archive of v2; a tool updating metadata imports but not the manifest (or vice versa); editing the manifest's imports to work around a missing dependency.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- durable capsule {} is missing its pinned contracts blob
- installed capsule identity/version differs from its authorit
- installed Capsule.toml differs from the exact manifest appro
- WASM capsule has no BLAKE3 hash in meta.json
- durable capsule {id} is missing WIT file {relative}
AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09).
Data as JSON: /api/errors/7143a5473095ef16.
Report an issue: GitHub.