{"record":{"id":"fb62349ab7089f85","repo":"astrid-runtime/astrid","slug":"legacy-audit-retirement-is-ambiguous-retired","errorCode":null,"errorMessage":"legacy audit retirement is ambiguous: {retired}","messagePattern":"legacy audit retirement is ambiguous: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/astrid-kernel/src/lib.rs","lineNumber":4276,"sourceCode":"            std::io::ErrorKind::InvalidInput,\n            \"legacy audit source has no parent\",\n        )\n    })?)?;\n    astrid_core::platform_fs::ensure_private_directory(&home.migrations_dir())?;\n    astrid_core::platform_fs::verify_no_redirects(&home.migrations_dir())?;\n    match std::fs::symlink_metadata(source) {\n        Ok(metadata) if metadata.file_type().is_symlink() || !metadata.is_dir() => {\n            return Err(std::io::Error::new(\n                std::io::ErrorKind::InvalidData,\n                format!(\n                    \"legacy audit source is not a regular directory: {}\",\n                    source.display()\n                ),\n            ));\n        },\n        Ok(_) => {\n            if std::fs::symlink_metadata(&retired).is_ok() {\n                return Err(std::io::Error::new(\n                    std::io::ErrorKind::AlreadyExists,\n                    format!(\n                        \"legacy audit retirement is ambiguous: {}\",\n                        retired.display()\n                    ),\n                ));\n            }\n            let root_device = audit_tree_device(&std::fs::symlink_metadata(source)?);\n            validate_audit_tree(source, root_device)?;\n            astrid_core::platform_fs::rename_with_write_through(source, &retired)?;\n            sync_audit_directory(source.parent().ok_or_else(|| {\n                std::io::Error::new(\n                    std::io::ErrorKind::InvalidInput,\n                    \"legacy audit source has no parent\",\n                )\n            })?)?;\n            sync_audit_directory(&home.migrations_dir())?;\n            validate_audit_tree(&retired, root_device)?;","sourceCodeStart":4258,"sourceCodeEnd":4294,"githubUrl":"https://github.com/astrid-runtime/astrid/blob/affd8760f44190dbdfbec23403f4c4b642c33112/crates/astrid-kernel/src/lib.rs#L4258-L4294","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\nmigrations/audit-principal-home.retired/   (stale target blocks rename)\n// after\nmv migrations/audit-principal-home.retired migrations/audit-principal-home.retired.bak-2026-09-09","handlingStrategy":"validation","validationCode":"let retired = home.migrations_dir().join(\"audit-principal-home.retired\");\nif std::fs::symlink_metadata(&retired).is_ok() {\n    // resolve or archive the stale target before re-running the migration\n}","typeGuard":"fn retirement_target_is_free(home: &Home) -> bool {\n    std::fs::symlink_metadata(home.migrations_dir().join(\"audit-principal-home.retired\")).is_err()\n}","tryCatchPattern":"match run_migration() {\n    Err(e) if e.kind() == std::io::ErrorKind::AlreadyExists\n        && e.to_string().contains(\"retirement is ambiguous\") => {\n        // archive the stale retired dir (e.g. .bak-<date>) and retry once\n    }\n    r => r?,\n}","preventionTips":["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"],"tags":["audit","migration","already-exists","rust"],"backgroundTag":"file-already-exists","analyzedSha":"affd8760f44190dbdfbec23403f4c4b642c33112","analyzedAt":"2026-09-09T21:28:12.402Z","contentChangedAt":"2026-09-09T21:28:12.402Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}