astrid-runtime/astrid · error

installed Capsule.toml differs from the exact manifest appro

Error message

installed Capsule.toml differs from the exact manifest approved at install; reinstall the capsule

What it means

The receipt stores the exact digest of the Capsule.toml approved at install. If the manifest file on disk hashes differently, even byte-level edits unrelated to capabilities invalidate the approval, since approvals are bound to the exact manifest bytes.

Source

Thrown at crates/astrid-capsule-install/src/authority.rs:581

            manifest.package.name,
            manifest.package.version
        );
    }
    let expansions = manifest
        .capabilities
        .expansions_from(&authority.approved_capabilities);
    if !expansions.is_empty() {
        let details = expansions
            .into_iter()
            .map(|expansion| format!("{}=[{}]", expansion.name, expansion.added.join(", ")))
            .collect::<Vec<_>>()
            .join("; ");
        bail!(
            "manifest exceeds its installed capability approval: {details}; reinstall and approve the expansion"
        );
    }
    if authority.manifest_digest != current_manifest_digest {
        bail!(
            "installed Capsule.toml differs from the exact manifest approved at install; reinstall the capsule"
        );
    }
    if !authority.wasm_hash_pinned {
        authority.wasm_hash_pinned = true;
        authority.approved_wasm_hash = executable_hash;
        AuthorityReceiptTransaction::stage(home, target_dir, &authority)?
            .commit()
            .context("failed to migrate installed authority executable pin")?;
    } else if authority.approved_wasm_hash != executable_hash {
        bail!(
            "installed WASM executable differs from its authority receipt (approved {}, found {})",
            authority
                .approved_wasm_hash
                .as_deref()
                .unwrap_or("<non-WASM>"),
            executable_hash.as_deref().unwrap_or("<non-WASM>"),
        );

View on GitHub (pinned to affd8760f4)

Solutions

  1. Reinstall the capsule so the current manifest bytes are re-approved and a new digest is stored
  2. Restore the original Capsule.toml exactly as approved (e.g. from version control)
  3. If the change is intentional, run the authorized install flow to approve the new manifest

Example fix

// before
// hand-edited installed Capsule.toml (whitespace/comment changes)
verify_installed_authority(&home, &target_dir, &manifest, None)?;
// after
git -C ~/.astrid/capsules/my-capsule checkout -- Capsule.toml
verify_installed_authority(&home, &target_dir, &manifest, None)?;
Defensive patterns

Strategy: validation

Validate before calling

let digest = blake3::hash(std::fs::read(target_dir.join("Capsule.toml"))?.as_slice()).to_hex();
if digest != approved_receipt.manifest_digest {
    return Err(anyhow!("Capsule.toml modified since approval; reinstall"));
}

Prevention

When it happens

Trigger: verify_installed_authority computes current_manifest_digest and finds it differs from authority.manifest_digest — any modification (formatting, comments, reordering) to the installed Capsule.toml after install.

Common situations: Hand-editing Capsule.toml after install (comments, formatting); tooling rewriting the manifest with normalized formatting; partially written manifest after an interrupted update.

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/bab240498865c1bf. Report an issue: GitHub.