{"record":{"id":"1e8b5c333f726de7","repo":"astrid-runtime/astrid","slug":"distro-lock-capsule-expected-resolves-to-insta","errorCode":null,"errorMessage":"Distro.lock capsule '{expected}' resolves to installed manifest '{actual}'; refusing to grant stale identity","messagePattern":"Distro\\.lock capsule '(.+?)' resolves to installed manifest '(.+?)'; refusing to grant stale identity","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/astrid-cli/src/commands/init_grant.rs","lineNumber":247,"sourceCode":"    let mut installed = Vec::with_capacity(locked.len());\n    for capsule in locked {\n        let expected = CapsuleId::new(capsule.name.clone())?;\n        let target_dir = super::super::capsule::install::resolve_target_dir_for(\n            home,\n            target,\n            expected.as_str(),\n            false,\n        )?;\n        let manifest_path = target_dir.join(\"Capsule.toml\");\n        let manifest = astrid_capsule::discovery::load_manifest(&manifest_path).with_context(|| {\n            format!(\n                \"Distro.lock is fresh but capsule '{}' is not installed correctly for '{}'; rerun init after removing the stale lock\",\n                capsule.name, target\n            )\n        })?;\n        let actual = CapsuleId::new(manifest.package.name.clone())?;\n        if actual != expected {\n            bail!(\n                \"Distro.lock capsule '{expected}' resolves to installed manifest '{actual}'; refusing to grant stale identity\"\n            );\n        }\n        let meta = super::super::capsule::meta::read_meta(&target_dir).ok_or_else(|| {\n            anyhow::anyhow!(\n                \"Distro.lock capsule '{}' has no readable install metadata for target '{}'\",\n                capsule.name,\n                target\n            )\n        })?;\n        if manifest.package.version != meta.version {\n            bail!(\n                \"installed capsule '{}' version disagrees between Capsule.toml ({}) and meta.json ({})\",\n                expected,\n                manifest.package.version,\n                meta.version\n            );\n        }","sourceCodeStart":229,"sourceCodeEnd":265,"githubUrl":"https://github.com/astrid-runtime/astrid/blob/affd8760f44190dbdfbec23403f4c4b642c33112/crates/astrid-cli/src/commands/init_grant.rs#L229-L265","documentation":"validate_locked_capsules_with_store cross-checks each capsule listed in Distro.lock against the actually installed capsule manifest. The CapsuleId derived from the installed manifest's package name must equal the expected id from the lock; otherwise the CLI refuses to grant permissions based on a stale identity and bails.","triggerScenarios":"During grant validation, the installed manifest at the capsule target resolves to a CapsuleId whose package name differs from the Distro.lock entry's expected CapsuleId.","commonSituations":"A capsule was renamed upstream while the lock still references the old name; the wrong capsule got installed at that path; a hand-edited or stale Distro.lock after switching distro versions.","solutions":["Rerun init (or the distro install) to regenerate Distro.lock from the currently installed capsules.","Remove the stale Distro.lock and reinstall so lock and installed identities agree.","If the capsule was renamed upstream, update the distro/lock to the new capsule name and reinstall.","Verify the install directory contains the correct capsule (check Capsule.toml package name)."],"exampleFix":"// before (Distro.lock)\nname = \"old-capsule-name\"   // installed manifest says \"new-capsule-name\"\n// after\nname = \"new-capsule-name\"   // regenerated via rerun of init/install","handlingStrategy":"validation","validationCode":"// before granting, compare lock vs installed manifest\nlet expected = CapsuleId::new(lock_entry.name.clone())?;\nlet manifest = read_manifest(target_dir)?;\nlet actual = CapsuleId::new(manifest.package.name.clone())?;\nif actual != expected {\n    eprintln!(\"stale lock: {expected} vs installed {actual}; rerun init\");\n}","typeGuard":null,"tryCatchPattern":"match result {\n    Err(e) if e.to_string().contains(\"refusing to grant stale identity\") => eprintln!(\"regenerate Distro.lock via init\"),\n    Err(e) => return Err(e),\n    Ok(v) => Ok(v),\n}","preventionTips":["Regenerate Distro.lock whenever capsules are renamed or distro versions change.","Never hand-edit Distro.lock entries.","Verify installed capsule package names after manual installs.","Rerun init after upstream capsule renames."],"tags":["lockfile","identity-mismatch","capsule"],"backgroundTag":"schema-validation-failed","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"}