astrid-runtime/astrid · error

Distro.lock capsule '{capsule}' does not declare WASM but in

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.

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)

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.