astrid-runtime/astrid · error

Distro.lock capsule ' ' does not declare WASM but installed…

Error message

Distro.lock capsule '{capsule}' does not declare WASM but installed metadata carries a WASM hash

What it means

The reverse consistency check: when the capsule manifest does not declare WASM but the installed metadata nevertheless carries a WASM hash, install state and manifest disagree. Validation refuses to proceed to avoid trusting artifact metadata the manifest never sanctioned.

Solutions

  1. Reinstall the capsule so metadata matches the current (non-WASM) manifest.
  2. Restore the wasm declaration in the manifest if WASM is actually shipped.
  3. Clear the stale installed metadata (WASM hash) for this capsule.
Defensive patterns

Strategy: validation

Validate before calling

if !manifest_declares_wasm(&manifest) && installed.wasm_hash.is_some() {
    return Err(anyhow!("stale wasm metadata for {}", capsule));
}

Try / catch

match validate_lock(&lock) {
    Err(e) if e.to_string().contains("does not declare WASM") => clear_stale_metadata(capsule)?,
    other => other?,
}

Prevention

When it happens

Trigger: validate_locked_wasm finds Some(meta_hash) while manifest_declares_wasm(manifest) == false.

Common situations: Manifest edited to remove WASM after the capsule was installed with WASM, leftover metadata from a previous WASM-capable version, or a mixed-version install across machines.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


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

Appendix: source

Thrown at crates/astrid-cli/src/commands/init_grant.rs:373

    capsule: &CapsuleId,
    manifest: &CapsuleManifest,
    meta_hash: Option<&str>,
    locked_hash: &str,
    store: Option<&astrid_storage::RuntimePrincipalStore>,
) -> anyhow::Result<()> {
    let declares_wasm = manifest_declares_wasm(manifest);
    let Some(meta_hash) = meta_hash else {
        if declares_wasm {
            bail!("Distro.lock capsule '{capsule}' declares WASM but has no installed WASM hash");
        }
        if !locked_hash.is_empty() {
            bail!("Distro.lock non-WASM capsule '{capsule}' must not carry a WASM hash");
        }
        return Ok(());
    };

    if !declares_wasm {
        bail!(
            "Distro.lock capsule '{capsule}' does not declare WASM but installed metadata carries a WASM hash"
        );
    }
    let locked = parse_locked_blake3(capsule, locked_hash)?;
    let locked_hex = locked.to_hex().to_string();
    if meta_hash != locked_hex {
        bail!("Distro.lock capsule '{capsule}' hash disagrees with installed metadata");
    }
    let bytes = if let Some(store) = store {
        let name = astrid_storage::ContentName::new(format!("bin/{locked_hex}.wasm"))?;
        let descriptor = store
            .content()
            .describe(&astrid_storage::StateOwner::System, &name)
            .map_err(|error| anyhow::anyhow!(error))?
            .ok_or_else(|| {
                anyhow::anyhow!(
                    "Distro.lock capsule '{capsule}' catalog entry is missing: bin/{locked_hex}.wasm"
                )

View on GitHub (pinned to affd8760f4)