astrid-runtime/astrid · error · io::Error

layout path has no existing directory ancestor: {}

Error message

layout path has no existing directory ancestor: {}

What it means

verify_existing_ancestor walks up the parent chain of a home path looking for an existing directory ancestor; if it exhausts the chain (candidate has no parent), it returns InvalidData. In practice this means the Astrid home path is so incomplete that not even a root-adjacent ancestor exists — the path is effectively empty or malformed, so preflight cannot establish a real filesystem anchor.

Source

Thrown at crates/astrid-core/src/dirs_layout.rs:437

}

fn verify_existing_ancestor(path: &Path) -> io::Result<()> {
    let mut candidate = path;
    loop {
        match std::fs::symlink_metadata(candidate) {
            Ok(metadata) if metadata.file_type().is_symlink() || !metadata.is_dir() => {
                return Err(io::Error::new(
                    io::ErrorKind::InvalidData,
                    format!(
                        "layout path is redirected or not a directory: {}",
                        candidate.display()
                    ),
                ));
            },
            Ok(_) => return crate::platform_fs::verify_no_redirects(candidate),
            Err(error) if error.kind() == io::ErrorKind::NotFound => {
                candidate = candidate.parent().ok_or_else(|| {
                    io::Error::new(
                        io::ErrorKind::InvalidData,
                        format!(
                            "layout path has no existing directory ancestor: {}",
                            path.display()
                        ),
                    )
                })?;
            },
            Err(error) => return Err(error),
        }
    }
}

fn path_entry_present(path: &Path) -> io::Result<bool> {
    match std::fs::symlink_metadata(path) {
        Ok(_) => Ok(true),
        Err(error) if error.kind() == io::ErrorKind::NotFound => Ok(false),
        Err(error) => Err(error),

View on GitHub (pinned to affd8760f4)

Solutions

  1. Verify the AstridHome root path is absolute, non-empty, and points where you intend
  2. Create the home root with std::fs::create_dir_all before invoking the migration APIs
  3. Fix path-construction bugs that produce empty or root-only paths (e.g. joining onto an empty base)
  4. Run the normal AstridHome::ensure initialization first so the directory skeleton exists before migration preflight runs

Example fix

// before: empty home path
let home = AstridHome::open(Path::new("")).unwrap();
home.begin_layout_v2_migration(&target)?; // InvalidData: no existing ancestor
// after
let root = Path::new("/var/lib/astrid");
std::fs::create_dir_all(root)?;
let home = AstridHome::open(root).unwrap();
home.begin_layout_v2_migration(&target)?;
Defensive patterns

Strategy: validation

Validate before calling

let root = home.root();
if root.as_os_str().is_empty() || !root.is_absolute() {
    return Err(anyhow!("home root must be a non-empty absolute path"));
}
std::fs::create_dir_all(root)?;

Type guard

fn is_usable_root(p: &Path) -> bool {
    !p.as_os_str().is_empty() && p.is_absolute()
}

Try / catch

match home.begin_layout_v2_migration(&target) {
    Err(e) if e.to_string().contains("no existing directory ancestor") => {
        // fix the home path and create the directory tree before retrying
    },
    r => r?,
}

Prevention

When it happens

Trigger: Calling begin_layout_v2_migration or complete_layout_v2 with a home root whose entire path chain is missing (candidate.parent() eventually returns None, e.g. root or relative path ""), or a path so broken no existing ancestor can be found.

Common situations: Passing an empty or malformed path as the Astrid home; running in a chroot/container where the home's parent directories were never created; constructing the home path programmatically with a bug that yields "/" or an empty PathBuf.

Related errors


AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09). Data as JSON: /api/errors/03a6dabbd2520e57. Report an issue: GitHub.