{"record":{"id":"a7679d5e14c07aa3","repo":"astrid-runtime/astrid","slug":"mountpoint-must-be-below-a-parent-directory","errorCode":null,"errorMessage":"mountpoint must be below a parent directory","messagePattern":"mountpoint must be below a parent directory","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/astrid-storage-provider-fskit/src/main.rs","lineNumber":538,"sourceCode":"fn validate_mountpoint_ancestors(mountpoint: &Path) -> Result<()> {\n    let _ = mountpoint;\n    Ok(())\n}\n\nfn validate_mountpoint_layout(mountpoint: &Path) -> Result<()> {\n    if !mountpoint.is_absolute() {\n        bail!(\"mountpoint must be absolute\");\n    }\n    if mountpoint.components().any(|component| {\n        matches!(\n            component,\n            std::path::Component::ParentDir | std::path::Component::CurDir\n        )\n    }) {\n        bail!(\"mountpoint contains traversal: {}\", mountpoint.display());\n    }\n    if mountpoint.parent().is_none() {\n        bail!(\"mountpoint must be below a parent directory\");\n    }\n    Ok(())\n}\n\n#[cfg(target_os = \"macos\")]\npub(crate) async fn native_mount(lease: &StorageMountLeaseV1, mountpoint: &Path) -> Result<()> {\n    let output = tokio::process::Command::new(\"/sbin/mount\")\n        .arg(\"-t\")\n        .arg(\"astridfs\")\n        .arg(&lease.resource_path)\n        .arg(mountpoint)\n        .output()\n        .await\n        .context(\"invoke macOS FSKit mount\")?;\n    if !output.status.success() {\n        let stderr = String::from_utf8_lossy(&output.stderr);\n        let stdout = String::from_utf8_lossy(&output.stdout);\n        bail!(native_mount_failure_message(","sourceCodeStart":520,"sourceCodeEnd":556,"githubUrl":"https://github.com/astrid-runtime/astrid/blob/affd8760f44190dbdfbec23403f4c4b642c33112/crates/astrid-storage-provider-fskit/src/main.rs#L520-L556","documentation":"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.","triggerScenarios":"Passing \"/\" or a path that resolves to root as the mountpoint to mount/unmount or the validate_* helpers.","commonSituations":"Defaulting an empty/missing config value to \"/\"; stripping too many components from a user path; a bug that produces Path::new(\"\") as the target.","solutions":["Choose a mountpoint at least one level below root, e.g. /Volumes/fskit-mnt","Reject empty or root paths in caller configuration before invoking the provider","Ensure any path-stripping logic cannot reduce the path to \"/\""],"exampleFix":"// before\nlet mountpoint = Path::new(\"/\");\n// after\nlet mountpoint = Path::new(\"/Volumes/fskit-mnt\");","handlingStrategy":"validation","validationCode":"fn ensure_below_root(mp: &std::path::Path) -> anyhow::Result<()> {\n    anyhow::ensure!(mp.parent().is_some(), \"mountpoint must be below a parent directory\");\n    Ok(())\n}","typeGuard":"fn has_parent(p: &std::path::Path) -> bool { p.parent().is_some() }","tryCatchPattern":null,"preventionTips":["Never default mountpoint config to \"/\" or empty string","Require explicit mountpoint configuration and validate on startup","Clamp path-reduction logic so it cannot yield root"],"tags":["filesystem","path-validation","mount"],"backgroundTag":"invalid-argument-value","analyzedSha":"affd8760f44190dbdfbec23403f4c4b642c33112","analyzedAt":"2026-09-09T21:28:12.402Z","contentChangedAt":"2026-09-09T21:28:12.402Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}