astrid-runtime/astrid · error
legacy audit retirement is ambiguous: {retired}
Error message
legacy audit retirement is ambiguous: {retired} What it means
After confirming the source audit directory exists, the routine checks that the retirement marker migrations_dir/audit-principal-home.retired does not already exist. If it does, the intended rename target is occupied, making the retirement state ambiguous (previous data vs. new move), so it aborts with AlreadyExists rather than overwrite anything.
Source
Thrown at crates/astrid-kernel/src/lib.rs:4276
std::io::ErrorKind::InvalidInput,
"legacy audit source has no parent",
)
})?)?;
astrid_core::platform_fs::ensure_private_directory(&home.migrations_dir())?;
astrid_core::platform_fs::verify_no_redirects(&home.migrations_dir())?;
match std::fs::symlink_metadata(source) {
Ok(metadata) if metadata.file_type().is_symlink() || !metadata.is_dir() => {
return Err(std::io::Error::new(
std::io::ErrorKind::InvalidData,
format!(
"legacy audit source is not a regular directory: {}",
source.display()
),
));
},
Ok(_) => {
if std::fs::symlink_metadata(&retired).is_ok() {
return Err(std::io::Error::new(
std::io::ErrorKind::AlreadyExists,
format!(
"legacy audit retirement is ambiguous: {}",
retired.display()
),
));
}
let root_device = audit_tree_device(&std::fs::symlink_metadata(source)?);
validate_audit_tree(source, root_device)?;
astrid_core::platform_fs::rename_with_write_through(source, &retired)?;
sync_audit_directory(source.parent().ok_or_else(|| {
std::io::Error::new(
std::io::ErrorKind::InvalidInput,
"legacy audit source has no parent",
)
})?)?;
sync_audit_directory(&home.migrations_dir())?;
validate_audit_tree(&retired, root_device)?;View on GitHub (pinned to affd8760f4)
Solutions
- Verify the existing audit-principal-home.retired contains the old audit data and delete it (or move it aside) before re-running
- Check whether the previous migration actually completed and skip the migration entirely if it did
- Rename the stale target (e.g. audit-principal-home.retired.bak-<date>) to unblock the rename
Example fix
// before migrations/audit-principal-home.retired/ (stale target blocks rename) // after mv migrations/audit-principal-home.retired migrations/audit-principal-home.retired.bak-2026-09-09
Defensive patterns
Strategy: validation
Validate before calling
let retired = home.migrations_dir().join("audit-principal-home.retired");
if std::fs::symlink_metadata(&retired).is_ok() {
// resolve or archive the stale target before re-running the migration
} Type guard
fn retirement_target_is_free(home: &Home) -> bool {
std::fs::symlink_metadata(home.migrations_dir().join("audit-principal-home.retired")).is_err()
} Try / catch
match run_migration() {
Err(e) if e.kind() == std::io::ErrorKind::AlreadyExists
&& e.to_string().contains("retirement is ambiguous") => {
// archive the stale retired dir (e.g. .bak-<date>) and retry once
}
r => r?,
} Prevention
- Check for an existing audit-principal-home.retired before re-running upgrades
- Treat the marker's presence as 'migration already done' and skip
- Archive stale retirement targets with a dated suffix instead of deleting
When it happens
Trigger: Re-running the legacy audit migration after a previous retirement already created audit-principal-home.retired, or when a stale/partial retirement target directory exists in migrations_dir.
Common situations: Retrying an upgrade that previously half-completed; restoring backups that recreated the retired directory; running the migration on a copied home directory that already contains the marker.
Understand the failure class
Background: "already exists" / EEXIST / FileAlreadyExistsException: what the 'file already exists' error means and how to fix it — this error's family across 37 libraries.
Related errors
- unsupported legacy audit source {audit_source}; only the def
- legacy audit retirement source is outside the default princi
- retire audit source
- legacy capsule entry has a non-UTF-8 name
- legacy capsule {id} authority verification produced no recei
AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09).
Data as JSON: /api/errors/fb62349ab7089f85.
Report an issue: GitHub.