astrid-runtime/astrid · error
legacy capsule authority receipt changed before retirement
Error message
legacy capsule authority receipt changed before retirement: {} What it means
Fired by retire_legacy_authority_receipt when the receipt bytes read from disk no longer match the published bytes that were verified earlier. The receipt mutated between verification and retirement, so deletion would discard changed content.
Solutions
- Investigate what modified the receipt (concurrent migration, tampering)
- Re-run the migration after the writer is stopped
- Restore the expected receipt or reinstall the capsule
Defensive patterns
Strategy: retry
When it happens
Trigger: Thrown at crates/astrid-capsule-install/src/authority.rs:273 when the library encounters an invalid state.
Common situations: See trigger scenarios.
AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09).
Data as JSON: /api/errors/f72aa8152d41725c.
Report an issue: GitHub.
Appendix: source
Thrown at crates/astrid-capsule-install/src/authority.rs:273
paths.active.display()
)
})?;
if metadata.file_type().is_symlink() || !metadata.is_file() {
bail!(
"legacy capsule authority receipt is not a regular file: {}",
paths.active.display()
);
}
astrid_core::platform_fs::verify_no_redirects(&paths.active).with_context(|| {
format!(
"verify legacy capsule authority receipt {}",
paths.active.display()
)
})?;
let actual = std::fs::read(&paths.active)
.with_context(|| format!("read legacy capsule authority {}", paths.active.display()))?;
if actual != expected_bytes {
bail!(
"legacy capsule authority receipt changed before retirement: {}",
paths.active.display()
);
}
// Re-stat and re-read immediately before unlinking. This does not turn a
// host filesystem into a transaction, but closes the ordinary mutation
// window exercised by migration/recovery and preserves a changed source.
let final_metadata = std::fs::symlink_metadata(&paths.active)?;
if final_metadata.file_type().is_symlink()
|| !final_metadata.is_file()
|| final_metadata.len() != actual.len() as u64
|| std::fs::read(&paths.active)?.as_slice() != expected_bytes
{
bail!(
"legacy capsule authority receipt changed during retirement: {}",
paths.active.display()
);
}View on GitHub (pinned to affd8760f4)