astrid-runtime/astrid · error
leftover capsule authority receipt is not a regular file: {}
Error message
leftover capsule authority receipt is not a regular file: {} What it means
`parse_legacy_authority_receipt` only accepts regular files as leftover authority receipts. This error is thrown when `symlink_metadata` shows the path is a symlink, directory, or other non-regular file. Receipts are security-sensitive: a symlink could redirect reads elsewhere, so the library hard-fails instead of following it (invalid JSON, by contrast, is tolerated as `Ok(None)`).
Source
Thrown at crates/astrid-capsule-install/src/authority/leftover.rs:71
);
}
if !status.previous.is_empty() {
bail!(
"cannot retire leftover capsule authority while previous transaction artifact exists at {}",
status.previous[0].display()
);
}
Ok(status.unknown_active)
}
/// Parse a regular-file leftover receipt. Invalid JSON returns `Ok(None)`.
pub(crate) fn parse_legacy_authority_receipt(
path: &Path,
) -> anyhow::Result<Option<(InstalledAuthority, Vec<u8>)>> {
let metadata = fs::symlink_metadata(path)
.with_context(|| format!("inspect leftover capsule authority {}", path.display()))?;
if metadata.file_type().is_symlink() || !metadata.is_file() {
bail!(
"leftover capsule authority receipt is not a regular file: {}",
path.display()
);
}
astrid_core::platform_fs::verify_no_redirects(path).with_context(|| {
format!(
"verify leftover capsule authority receipt {}",
path.display()
)
})?;
let bytes = fs::read(path)
.with_context(|| format!("read leftover capsule authority {}", path.display()))?;
let Ok(receipt) = serde_json::from_slice::<InstalledAuthority>(&bytes) else {
return Ok(None);
};
if receipt.schema_version != 1 {
return Ok(None);
}View on GitHub (pinned to affd8760f4)
Solutions
- Replace the symlink or non-regular entry with a real regular-file receipt (copy the target's bytes into the authority directory), then retry
- If the entry is not a valid receipt, remove it or quarantine it manually and rerun the leftover sweep
- Audit the home's authority receipt directory for symlinks and ensure restore/copy tooling dereferences symlinks into plain files
Example fix
// before: authority dir contains a symlinked receipt
bail!("leftover capsule authority receipt is not a regular file: {}", path.display());
// after: replace symlink with a regular file
// let target = fs::read_link(&path)?;
// fs::remove_file(&path)?;
// fs::copy(target, &path)?; // then retry the sweep Defensive patterns
Strategy: validation
Validate before calling
// Inspect leftover receipt paths before parsing
let metadata = fs::symlink_metadata(&path)?;
if metadata.file_type().is_symlink() || !metadata.is_file() {
// replace with a regular file or quarantine the entry before the sweep
} Type guard
fn is_regular_file(path: &Path) -> bool {
std::fs::symlink_metadata(path)
.map(|m| !m.file_type().is_symlink() && m.is_file())
.unwrap_or(false)
} Try / catch
match parse_legacy_authority_receipt(&path) {
Err(e) if e.to_string().contains("not a regular file") => quarantine_or_replace(&path)?,
other => other,
} Prevention
- Never symlink receipts into or out of the authority directory
- Configure backup/restore tooling to materialize copies, not symlinks
- Audit the authority receipt directory for symlinks and odd entries after restores
- Use quarantine or retirement flows instead of hand-placing files in receipt directories
When it happens
Trigger: Calling `parse_legacy_authority_receipt` (used by `unique_relocated_receipt`, `leftover_id_counts`, `retire_one_leftover`) on a path inside the legacy authority directory that is a symlink or not a regular file — e.g. someone symlinked a receipt to another location, or a directory was created where a receipt file should be.
Common situations: User convenience symlinks placed into the authority receipt directory to share receipts across homes; backup/restore tools that replaced files with symlinks; a directory accidentally created where a `.json` receipt belongs.
Understand the failure class
Background: "is not a compatible type" / "cannot merge" errors: when a value's type doesn't match what the library requires — this error's family across 65 libraries.
Related errors
- legacy capsule authority root is not a regular directory: {}
- legacy capsule authority root contains a non-regular entry:
- legacy capsule authority root is not a regular directory: {}
- directory symlink {} not allowed in capsule source tree (ref
- cache changed to a redirect or special entry: {}
AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09).
Data as JSON: /api/errors/f2fa4f261ac318aa.
Report an issue: GitHub.