astrid-runtime/astrid · error

Distro.lock capsule '{capsule}' hash disagrees with installe

Error message

Distro.lock capsule '{capsule}' hash disagrees with installed metadata

What it means

After parsing the locked blake3 hash, the CLI compares it against the WASM hash recorded in installed metadata. Any difference means the artifact installed on disk is not the one pinned in Distro.lock, so granting proceeds only after the hashes agree.

Source

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

    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"
                )
            })?;
        store
            .content()
            .read_range(
                &astrid_storage::StateOwner::System,
                &name,
                0,

View on GitHub (pinned to affd8760f4)

Solutions

  1. Reinstall the capsule so its installed WASM hash equals the Distro.lock hash.
  2. Regenerate Distro.lock to record the hash of the currently installed artifact.
  3. Verify no build non-determinism: rebuild from the same source/toolchain and compare hashes.
Defensive patterns

Strategy: validation

Validate before calling

let locked_hex = blake3::Hash::from_str(locked_hash.strip_prefix("blake3:")?)?.to_hex().to_string();
if installed.wasm_hash.as_deref() != Some(locked_hex.as_str()) {
    return Err(anyhow!("installed hash != locked hash for {}", capsule));
}

Try / catch

if let Err(e) = validate_lock(&lock) {
    if e.to_string().contains("hash disagrees with installed metadata") {
        reinstall_or_relock().await?;
    } else { return Err(e.into()); }
}

Prevention

When it happens

Trigger: validate_locked_wasm computes locked_hex from parse_locked_blake3(capsule, locked_hash) and bails when meta_hash != locked_hex.

Common situations: Capsule rebuilt/reinstalled since the lock was generated, metadata recording a hash with different casing or content, lockfile committed before a final rebuild, or artifact swapped in the content store.

Understand the failure class

Background: Checksum mismatch errors: "checksum verification failed", "digest mismatch", "expected vs actual checksum" — what they mean and how to fix them — this error's family across 41 libraries.

Related errors


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