astrid-runtime/astrid · error
Distro.lock capsule '{expected}' resolves to installed manif
Error message
Distro.lock capsule '{expected}' resolves to installed manifest '{actual}'; refusing to grant stale identity What it means
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.
Source
Thrown at crates/astrid-cli/src/commands/init_grant.rs:247
let mut installed = Vec::with_capacity(locked.len());
for capsule in locked {
let expected = CapsuleId::new(capsule.name.clone())?;
let target_dir = super::super::capsule::install::resolve_target_dir_for(
home,
target,
expected.as_str(),
false,
)?;
let manifest_path = target_dir.join("Capsule.toml");
let manifest = astrid_capsule::discovery::load_manifest(&manifest_path).with_context(|| {
format!(
"Distro.lock is fresh but capsule '{}' is not installed correctly for '{}'; rerun init after removing the stale lock",
capsule.name, target
)
})?;
let actual = CapsuleId::new(manifest.package.name.clone())?;
if actual != expected {
bail!(
"Distro.lock capsule '{expected}' resolves to installed manifest '{actual}'; refusing to grant stale identity"
);
}
let meta = super::super::capsule::meta::read_meta(&target_dir).ok_or_else(|| {
anyhow::anyhow!(
"Distro.lock capsule '{}' has no readable install metadata for target '{}'",
capsule.name,
target
)
})?;
if manifest.package.version != meta.version {
bail!(
"installed capsule '{}' version disagrees between Capsule.toml ({}) and meta.json ({})",
expected,
manifest.package.version,
meta.version
);
}View on GitHub (pinned to affd8760f4)
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).
Example fix
// before (Distro.lock) name = "old-capsule-name" // installed manifest says "new-capsule-name" // after name = "new-capsule-name" // regenerated via rerun of init/install
Defensive patterns
Strategy: validation
Validate before calling
// before granting, compare lock vs installed manifest
let expected = CapsuleId::new(lock_entry.name.clone())?;
let manifest = read_manifest(target_dir)?;
let actual = CapsuleId::new(manifest.package.name.clone())?;
if actual != expected {
eprintln!("stale lock: {expected} vs installed {actual}; rerun init");
} Try / catch
match result {
Err(e) if e.to_string().contains("refusing to grant stale identity") => eprintln!("regenerate Distro.lock via init"),
Err(e) => return Err(e),
Ok(v) => Ok(v),
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- durable capsule {id} identity differs across archive and aut
- legacy capsule authority identity differs for {id}
- signed Distro.lock entry '{}' does not match Distro.toml
- cannot remove capsule authority while an install transaction
- an incomplete capsule authority update exists at {}; remove
AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09).
Data as JSON: /api/errors/1e8b5c333f726de7.
Report an issue: GitHub.