{"record":{"id":"5d513136ac7da4bc","repo":"astrid-runtime/astrid","slug":"distro-lock-capsule-capsule-hash-disagrees-wit","errorCode":null,"errorMessage":"Distro.lock capsule '{capsule}' hash disagrees with installed metadata","messagePattern":"Distro\\.lock capsule '(.+?)' hash disagrees with installed metadata","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/astrid-cli/src/commands/init_grant.rs","lineNumber":380,"sourceCode":"    let Some(meta_hash) = meta_hash else {\n        if declares_wasm {\n            bail!(\"Distro.lock capsule '{capsule}' declares WASM but has no installed WASM hash\");\n        }\n        if !locked_hash.is_empty() {\n            bail!(\"Distro.lock non-WASM capsule '{capsule}' must not carry a WASM hash\");\n        }\n        return Ok(());\n    };\n\n    if !declares_wasm {\n        bail!(\n            \"Distro.lock capsule '{capsule}' does not declare WASM but installed metadata carries a WASM hash\"\n        );\n    }\n    let locked = parse_locked_blake3(capsule, locked_hash)?;\n    let locked_hex = locked.to_hex().to_string();\n    if meta_hash != locked_hex {\n        bail!(\"Distro.lock capsule '{capsule}' hash disagrees with installed metadata\");\n    }\n    let bytes = if let Some(store) = store {\n        let name = astrid_storage::ContentName::new(format!(\"bin/{locked_hex}.wasm\"))?;\n        let descriptor = store\n            .content()\n            .describe(&astrid_storage::StateOwner::System, &name)\n            .map_err(|error| anyhow::anyhow!(error))?\n            .ok_or_else(|| {\n                anyhow::anyhow!(\n                    \"Distro.lock capsule '{capsule}' catalog entry is missing: bin/{locked_hex}.wasm\"\n                )\n            })?;\n        store\n            .content()\n            .read_range(\n                &astrid_storage::StateOwner::System,\n                &name,\n                0,","sourceCodeStart":362,"sourceCodeEnd":398,"githubUrl":"https://github.com/astrid-runtime/astrid/blob/affd8760f44190dbdfbec23403f4c4b642c33112/crates/astrid-cli/src/commands/init_grant.rs#L362-L398","documentation":"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.","triggerScenarios":"validate_locked_wasm computes locked_hex from parse_locked_blake3(capsule, locked_hash) and bails when meta_hash != locked_hex.","commonSituations":"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.","solutions":["Reinstall the capsule so its installed WASM hash equals the Distro.lock hash.","Regenerate Distro.lock to record the hash of the currently installed artifact.","Verify no build non-determinism: rebuild from the same source/toolchain and compare hashes."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"let locked_hex = blake3::Hash::from_str(locked_hash.strip_prefix(\"blake3:\")?)?.to_hex().to_string();\nif installed.wasm_hash.as_deref() != Some(locked_hex.as_str()) {\n    return Err(anyhow!(\"installed hash != locked hash for {}\", capsule));\n}","typeGuard":null,"tryCatchPattern":"if let Err(e) = validate_lock(&lock) {\n    if e.to_string().contains(\"hash disagrees with installed metadata\") {\n        reinstall_or_relock().await?;\n    } else { return Err(e.into()); }\n}","preventionTips":["Re-run the lockfile generation step as part of every release build.","Verify installed hashes right after each capsule install.","Avoid rebuilding artifacts between lockfile creation and deployment."],"tags":["checksum-mismatch","hash","lockfile","metadata"],"backgroundTag":"checksum-mismatch","analyzedSha":"affd8760f44190dbdfbec23403f4c4b642c33112","analyzedAt":"2026-09-09T21:28:12.402Z","contentChangedAt":"2026-09-09T21:28:12.402Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}