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

  1. Regenerate the durable metadata from the current archive so metadata.imports matches manifest.imports.
  2. Reinstall the capsule from a single consistent published archive + metadata set.
  3. If the imports change is intentional, republish the capsule (new version) and reinstall so all records update together.
  4. 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

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


AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09). Data as JSON: /api/errors/7143a5473095ef16. Report an issue: GitHub.