astrid-runtime/astrid · error
legacy audit retirement is ambiguous: {}
Error message
legacy audit retirement is ambiguous: {} What it means
Before renaming the legacy audit directory into the migrations staging area, retire_legacy_audit_dir checks whether the staging target <migrations_dir>/audit-principal-home.retired already exists. If it does, the outcome of a previous run is ambiguous (already retired? partially deleted?), so the library fails with AlreadyExists instead of overwriting data. This makes interrupted migrations resumable via a deliberate decision rather than silent data loss.
Source
Thrown at crates/astrid-kernel/src/legacy_migration_barrier/host_fs.rs:475
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 fs::symlink_metadata(source) {
Ok(metadata) if metadata.file_type().is_symlink() || !metadata.is_dir() => {
return Err(io::Error::new(
io::ErrorKind::InvalidData,
format!(
"legacy audit source is not a regular directory: {}",
source.display()
),
));
},
Ok(_) => {
if fs::symlink_metadata(&retired).is_ok() {
return Err(io::Error::new(
io::ErrorKind::AlreadyExists,
format!(
"legacy audit retirement is ambiguous: {}",
retired.display()
),
));
}
let root_device = device_id(&fs::symlink_metadata(source)?);
validate_audit_tree(source, root_device)?;
astrid_core::platform_fs::rename_with_write_through(source, &retired)?;
sync_directory(source.parent().ok_or_else(|| {
io::Error::new(
io::ErrorKind::InvalidInput,
"legacy audit source has no parent",
)
})?)?;
sync_directory(&home.migrations_dir())?;
validate_audit_tree(&retired, root_device)?;View on GitHub (pinned to affd8760f4)
Solutions
- Re-run migrate_legacy_audit: the NotFound branch resumes cleanup of an existing .retired staging dir when the source is gone.
- If the source still exists and a stale .retired dir remains, verify the .retired content is unwanted, then remove <migrations_dir>/audit-principal-home.retired manually and retry.
- Never reuse or restore the .retired path yourself; let the migration's resume logic validate and delete it.
Example fix
// before: ambiguous leftover blocks retry ls ~/.astrid/migrations/ # audit-principal-home.retired exists // after: clear the stale staging target after verifying it rm -rf ~/.astrid/migrations/audit-principal-home.retired migrate_legacy_audit(&home, &source)?;
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() {
// either re-run migration to resume cleanup, or remove the stale staging dir after inspection
eprintln!("stale staging dir: {}", retired.display());
} Type guard
fn staging_clear(home: &AstridHome) -> bool {
std::fs::symlink_metadata(home.migrations_dir().join("audit-principal-home.retired")).is_err()
} Try / catch
if let Err(e) = migrate_legacy_audit(&home, &source) {
if e.kind() == std::io::ErrorKind::AlreadyExists && e.to_string().contains("ambiguous") {
// inspect/remove audit-principal-home.retired, then retry
}
} Prevention
- Do not interrupt migrations between rename and delete; re-run to resume.
- Never manually create files named *.retired in the migrations dir.
- After a crash, check migrations_dir for leftover staging entries before retrying.
When it happens
Trigger: Calling migrate_legacy_audit twice after a first run crashed between the rename and the final delete_audit_tree, leaving the .retired staging directory behind; or any pre-existing file/directory named audit-principal-home.retired in the migrations dir.
Common situations: A previous migration was interrupted by crash/kill/power loss after rename but before deletion; leftover staging dir from a failed run that was never cleaned; manual copies placed in the migrations directory.
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
- legacy and operator REPL histories differ; refusing to merge
- legacy distro conflict at {path}: {detail}
- legacy log conflict at {}: {detail}
- legacy capsule directory is not a regular directory: {}
- legacy capsule entry is not a regular directory: {}
AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09).
Data as JSON: /api/errors/c9965dc6f583b382.
Report an issue: GitHub.