astrid-runtime/astrid · error
legacy principal-home entry is not a regular directory: {}
Error message
legacy principal-home entry is not a regular directory: {} What it means
While enumerating the principal home root, preflight_legacy_audit_sources requires every entry to be a regular directory (no symlinks, files, or special files) before treating it as a principal home. A symlinked or non-directory entry could redirect the importer into an unintended subtree, so the scan aborts with InvalidData naming the offending entry.
Source
Thrown at crates/astrid-kernel/src/legacy_migration_barrier/host_fs.rs:381
io::ErrorKind::InvalidData,
format!(
"legacy principal-home root is not a directory: {}",
root.display()
),
));
},
Ok(metadata) => metadata,
Err(error) if error.kind() == io::ErrorKind::NotFound => return Ok(false),
Err(error) => return Err(error),
};
let root_device = device_id(&metadata);
let mut default_source_present = false;
astrid_core::platform_fs::verify_no_redirects(&root)?;
for entry in fs::read_dir(&root).map_err(io::Error::other)? {
let principal_root = entry.map_err(io::Error::other)?.path();
let principal_metadata = fs::symlink_metadata(&principal_root).map_err(io::Error::other)?;
if principal_metadata.file_type().is_symlink() || !principal_metadata.is_dir() {
return Err(io::Error::new(
io::ErrorKind::InvalidData,
format!(
"legacy principal-home entry is not a regular directory: {}",
principal_root.display()
),
));
}
if device_id(&principal_metadata) != root_device {
return Err(io::Error::new(
io::ErrorKind::InvalidData,
format!(
"legacy principal-home entry crosses a filesystem boundary: {}",
principal_root.display()
),
));
}
astrid_core::platform_fs::verify_no_redirects(&principal_root)?;
let local_root = principal_root.join(".local");View on GitHub (pinned to affd8760f4)
Solutions
- Inspect the reported entry (ls -la) and replace the symlink/file with a real directory if it should be a principal home.
- Move unrelated files, sockets, or symlinks out of the home root so it contains only directories.
- If the entry is a symlink to real data, replace it with the actual directory (copy or move the target).
- Re-run migrate_legacy_audit after the root contains only regular directories.
Example fix
// before lrwxrwxrwx principal-7f3a -> /mnt/data/principal-7f3a // after $ rm principal-7f3a && mv /mnt/data/principal-7f3a . && chmod 700 principal-7f3a
Defensive patterns
Strategy: validation
Validate before calling
fn scan_home_root(root: &std::path::Path) -> std::io::Result<Vec<std::path::PathBuf>> {
let mut bad = Vec::new();
for e in std::fs::read_dir(root)? {
let p = e?.path();
let m = std::fs::symlink_metadata(&p)?;
if m.file_type().is_symlink() || !m.is_dir() {
bad.push(p);
}
}
Ok(bad) // must be empty before migrating
} Type guard
fn entry_is_plain_dir(p: &std::path::Path) -> bool {
std::fs::symlink_metadata(p).map(|m| !m.file_type().is_symlink() && m.is_dir()).unwrap_or(false)
} Try / catch
match result {
Err(e) if e.kind() == std::io::ErrorKind::InvalidData && e.to_string().contains("not a regular directory") => {
// clean non-directory entries out of the home root, then retry
}
other => other?,
} Prevention
- Keep only regular directories directly under the home root.
- Run find <home-root> -mindepth 1 -maxdepth 1 ! -type d to spot offending entries first.
- Move stray files/sockets elsewhere; never symlink principal directories.
When it happens
Trigger: migrate_legacy_audit finds any entry directly under the home root where symlink_metadata reports is_symlink() || !is_dir() (host_fs.rs:380) — e.g. a symlinked principal directory, a stray file, a socket or device node placed in the home root.
Common situations: Symlinking a per-principal directory to another disk; temporary files or sockets dropped into the home root; a partially-created principal directory replaced by a placeholder file.
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 root is not a directory: {}
- legacy capsule directory is not a regular directory: {}
- legacy capsule entry is not a regular directory: {}
- legacy env/secret path is not a regular directory: {}
- legacy REPL history is not a regular file: {}
AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09).
Data as JSON: /api/errors/d54d2d70987c235f.
Report an issue: GitHub.