astrid-runtime/astrid · error
legacy audit tree is redirected or not a directory
Error message
legacy audit tree is redirected or not a directory: {} What it means
validate_audit_tree checks each node of the legacy audit tree (no-follow, via symlink_metadata) and rejects any node that is a symlink or not a directory with InvalidData. The migration barrier requires the audit tree to consist solely of plain directories and regular files; redirected nodes could point outside the tree and cause data outside the legacy layout to be renamed or deleted.
Solutions
- Replace every symlink inside (or at the root of) the audit tree with a real directory containing the data.
- Remove or rename non-directory entries that occupy paths expected to be directories.
- Re-run the migration after the tree contains only plain directories and regular files.
Example fix
// before ln -s /var/lib/audit ~/.astrid/principal/audit // after rm ~/.astrid/principal/audit mv /var/lib/audit ~/.astrid/principal/audit
Defensive patterns
Strategy: validation
Validate before calling
fn audit_tree_is_plain(root: &Path) -> std::io::Result<bool> {
for entry in std::fs::read_dir(root)? {
let m = std::fs::symlink_metadata(entry?.path())?;
if m.file_type().is_symlink() { return Ok(false); }
}
Ok(true)
} Type guard
fn is_plain_tree_node(p: &Path) -> bool {
std::fs::symlink_metadata(p).map(|m| m.is_dir() && !m.file_type().is_symlink()).unwrap_or(false)
} Try / catch
if let Err(e) = migrate_legacy_audit(&home, &source) {
if e.to_string().contains("redirected or not a directory") {
// dereference/replace symlinks, then retry
}
} Prevention
- Keep dotfile managers away from ~/.astrid.
- Run find <audit-dir> -type l before migrating and replace links with copies.
- Document that the audit tree must contain only real dirs and files.
When it happens
Trigger: Preflighting, retiring, or deleting a legacy audit tree while any node on the path (root or reached during recursion) is a symlink or a non-directory (file passed at directory level, fifo, etc.). Called from preflight_legacy_audit_sources, retire_legacy_audit_dir, validate_audit_tree (recursive), and delete_audit_tree.
Common situations: Dotfile managers symlinking parts of ~/.astrid; an 'audit' path that is actually a file; symlinked subdirectories inside the audit tree pointing to external storage.
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 principal-home entry is not a regular directory
- legacy principal-home root is not a directory
- legacy principal home root is not a regular directory
- legacy principal profile is not a regular file
- Astrid durable media is redirected or not a regular file
AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09).
Data as JSON: /api/errors/db0fe7999baba08b.
Report an issue: GitHub.
Appendix: source
Thrown at crates/astrid-kernel/src/legacy_migration_barrier/host_fs.rs:514
},
Err(error) if error.kind() == io::ErrorKind::NotFound => {
if fs::symlink_metadata(&retired).is_ok() {
let root_device = device_id(&fs::symlink_metadata(&retired)?);
validate_audit_tree(&retired, root_device)?;
delete_audit_tree(&retired, root_device)?;
sync_directory(&home.migrations_dir())?;
}
},
Err(error) => return Err(error),
}
Ok(())
}
#[cfg(not(unix))]
fn validate_audit_tree(path: &Path, root_device: u64) -> io::Result<()> {
let metadata = fs::symlink_metadata(path)?;
if metadata.file_type().is_symlink() || !metadata.is_dir() {
return Err(io::Error::new(
io::ErrorKind::InvalidData,
format!(
"legacy audit tree is redirected or not a directory: {}",
path.display()
),
));
}
if device_id(&metadata) != root_device || active_mountpoint(path)? {
return Err(io::Error::new(
io::ErrorKind::InvalidData,
format!(
"legacy audit tree crosses a filesystem or mount boundary: {}",
path.display()
),
));
}
astrid_core::platform_fs::verify_no_redirects(path)?;
for entry in fs::read_dir(path).map_err(io::Error::other)? {View on GitHub (pinned to affd8760f4)