astrid-runtime/astrid · error

legacy audit source has no parent

Error message

legacy audit source has no parent

What it means

During legacy audit-directory retirement (retire_legacy_audit_dir), the code calls source.parent() on the audit source path to verify the parent directory has no redirects (symlinks/redirect files) before renaming. Path::parent() returns None only for a root path (e.g. "/") or an empty path, so this error means the source path was so degenerate that it has no parent component. The library throws it as InvalidInput because retirement of a root-level path is never a legitimate legacy audit location.

Source

Thrown at crates/astrid-kernel/src/legacy_migration_barrier/host_fs.rs:456

    }
    Ok(default_source_present)
}

/// Retire the imported default audit tree through a private staging rename.
/// The rename makes interrupted deletion resumable, while every pre/post
/// traversal revalidates no-follow, regular-entry, device, and mount bounds.
#[cfg(not(unix))]
pub(super) fn retire_legacy_audit_dir(home: &AstridHome, source: &Path) -> io::Result<()> {
    let retired = home.migrations_dir().join("audit-principal-home.retired");
    let expected = home.principal_home(&PrincipalId::default()).audit_dir();
    if source != expected {
        return Err(io::Error::new(
            io::ErrorKind::InvalidInput,
            "legacy audit retirement source is outside the default principal audit path",
        ));
    }
    astrid_core::platform_fs::verify_no_redirects(source.parent().ok_or_else(|| {
        io::Error::new(
            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() {

View on GitHub (pinned to affd8760f4)

Solutions

  1. Fix the legacy home configuration so the principal audit path is a real subdirectory (e.g. <home>/audit), not "/" or an empty path.
  2. Inspect how the source path is constructed and ensure at least one parent component exists before calling migrate_legacy_audit.
  3. Validate the configured home path with Path::parent().is_some() (and that it is not root) before invoking migration.

Example fix

// before
let source = Path::new(""); // empty -> parent() is None
migrate_legacy_audit(&home, source)?;
// after
let source = home.principal_home(&PrincipalId::default()).audit_dir();
assert!(source.parent().is_some());
migrate_legacy_audit(&home, &source)?;
Defensive patterns

Strategy: validation

Validate before calling

let source = home.principal_home(&PrincipalId::default()).audit_dir();
if source.parent().is_none() || source == Path::new("/") {
    return Err(format!("invalid legacy audit source: {}", source.display()));
}
migrate_legacy_audit(&home, &source)?;

Type guard

fn has_parent(p: &Path) -> bool { p.parent().is_some() && p != Path::new("/") }

Try / catch

match migrate_legacy_audit(&home, &source) {
    Err(e) if e.to_string().contains("has no parent") => fix_source_path(),
    other => other?,
}

Prevention

When it happens

Trigger: Calling migrate_legacy_audit with a source path that resolves to "/" or an empty path, such that Path::parent() returns None when verifying redirects on the parent before the staging rename.

Common situations: Misconfigured legacy home directory pointing at the filesystem root; a home/config resolver that returns an empty string which becomes an empty Path; tests or scripts passing "/" as the principal home.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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