astrid-runtime/astrid · error

mountpoint must be below a parent directory

Error message

mountpoint must be below a parent directory

What it means

As a final layout rule, validate_mountpoint_layout requires that mountpoint.parent() returns Some — i.e. the path must have a parent directory and not be a bare root like "/" or a single component. Mounting over the filesystem root or a path without a distinct parent is unsafe, so the provider refuses.

Source

Thrown at crates/astrid-storage-provider-fskit/src/main.rs:538

fn validate_mountpoint_ancestors(mountpoint: &Path) -> Result<()> {
    let _ = mountpoint;
    Ok(())
}

fn validate_mountpoint_layout(mountpoint: &Path) -> Result<()> {
    if !mountpoint.is_absolute() {
        bail!("mountpoint must be absolute");
    }
    if mountpoint.components().any(|component| {
        matches!(
            component,
            std::path::Component::ParentDir | std::path::Component::CurDir
        )
    }) {
        bail!("mountpoint contains traversal: {}", mountpoint.display());
    }
    if mountpoint.parent().is_none() {
        bail!("mountpoint must be below a parent directory");
    }
    Ok(())
}

#[cfg(target_os = "macos")]
pub(crate) async fn native_mount(lease: &StorageMountLeaseV1, mountpoint: &Path) -> Result<()> {
    let output = tokio::process::Command::new("/sbin/mount")
        .arg("-t")
        .arg("astridfs")
        .arg(&lease.resource_path)
        .arg(mountpoint)
        .output()
        .await
        .context("invoke macOS FSKit mount")?;
    if !output.status.success() {
        let stderr = String::from_utf8_lossy(&output.stderr);
        let stdout = String::from_utf8_lossy(&output.stdout);
        bail!(native_mount_failure_message(

View on GitHub (pinned to affd8760f4)

Solutions

  1. Choose a mountpoint at least one level below root, e.g. /Volumes/fskit-mnt
  2. Reject empty or root paths in caller configuration before invoking the provider
  3. Ensure any path-stripping logic cannot reduce the path to "/"

Example fix

// before
let mountpoint = Path::new("/");
// after
let mountpoint = Path::new("/Volumes/fskit-mnt");
Defensive patterns

Strategy: validation

Validate before calling

fn ensure_below_root(mp: &std::path::Path) -> anyhow::Result<()> {
    anyhow::ensure!(mp.parent().is_some(), "mountpoint must be below a parent directory");
    Ok(())
}

Type guard

fn has_parent(p: &std::path::Path) -> bool { p.parent().is_some() }

Prevention

When it happens

Trigger: Passing "/" or a path that resolves to root as the mountpoint to mount/unmount or the validate_* helpers.

Common situations: Defaulting an empty/missing config value to "/"; stripping too many components from a user path; a bug that produces Path::new("") as the target.

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/a7679d5e14c07aa3. Report an issue: GitHub.