{"record":{"id":"e77366835c49e33f","repo":"astrid-runtime/astrid","slug":"mountpoint-parent-is-not-a-directory","errorCode":null,"errorMessage":"mountpoint parent is not a directory: {}","messagePattern":"mountpoint parent is not a directory: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/astrid-storage-provider-winfsp/src/main.rs","lineNumber":364,"sourceCode":"    if is_drive_target(&mountpoint) {\n        if std::fs::metadata(&mountpoint).is_ok() {\n            bail!(\n                \"Windows drive target is already in use: {}\",\n                mountpoint.display()\n            );\n        }\n        return Ok((mountpoint, false));\n    }\n\n    let parent = mountpoint\n        .parent()\n        .context(\"WinFsp directory mountpoint has no parent\")?;\n    std::fs::create_dir_all(parent)\n        .with_context(|| format!(\"create mountpoint parent {}\", parent.display()))?;\n    astrid_core::platform_fs::verify_no_redirects(parent)\n        .with_context(|| format!(\"reject redirected mountpoint parent {}\", parent.display()))?;\n    if !std::fs::symlink_metadata(parent)?.is_dir() {\n        bail!(\"mountpoint parent is not a directory: {}\", parent.display());\n    }\n    match std::fs::symlink_metadata(&mountpoint) {\n        Err(error) if error.kind() == std::io::ErrorKind::NotFound => {},\n        Err(error) => {\n            return Err(error)\n                .with_context(|| format!(\"inspect mountpoint {}\", mountpoint.display()));\n        },\n        Ok(_) => bail!(\n            \"WinFsp directory mountpoint must not already exist: {}\",\n            mountpoint.display()\n        ),\n    }\n    // WinFsp creates and owns directory mountpoint leaves. Treat the leaf as\n    // provider-created so failure and unmount cleanup remain idempotent.\n    Ok((mountpoint, true))\n}\n\n#[cfg(not(windows))]","sourceCodeStart":346,"sourceCodeEnd":382,"githubUrl":"https://github.com/astrid-runtime/astrid/blob/affd8760f44190dbdfbec23403f4c4b642c33112/crates/astrid-storage-provider-winfsp/src/main.rs#L346-L382","documentation":"For directory mountpoints, `prepare_mountpoint` creates the parent directory, verifies it has no filesystem redirects (e.g. OneDrive/cloud placeholder reparse points), and then confirms via `symlink_metadata` that the parent really is a directory. If the parent exists but is a symlink to a file, a regular file, or another non-directory entry, the provider refuses with this error rather than letting WinFsp fail obscurely later.","triggerScenarios":"Requesting a directory mountpoint whose parent path (after `create_dir_all`) exists but is not a directory — e.g. `C:\\data\\file.txt\\leaf` where `file.txt` is a regular file, or a parent that is a file-type symlink/reparse point surviving the redirect check.","commonSituations":"Typo in the mount path causing a filename to be used as a directory; a file was created earlier at the intended parent path; junction/symlink structures left over from previous setups.","solutions":["Inspect the parent path reported in the error and ensure it is a real directory (delete or rename the file/symlink occupying it)","Correct the requested mountpoint path so its parent is a legitimate directory","Re-run `fsutil reparsepoint query` / check attributes if reparse points are involved and remove unexpected ones"],"exampleFix":"// before: parent is a file\nmount(provider, Some(PathBuf::from(\"C:\\\\notes.txt\\\\storage\"))).await?;\n// after: parent is a directory\nstd::fs::create_dir_all(\"C:\\\\mounts\")?;\nmount(provider, Some(PathBuf::from(\"C:\\\\mounts\\\\storage\"))).await?;","handlingStrategy":"validation","validationCode":"// Verify parent is a real directory before mounting\nfn parent_is_dir(mountpoint: &std::path::Path) -> std::io::Result<bool> {\n    let parent = mountpoint.parent().ok_or_else(|| std::io::Error::new(std::io::ErrorKind::NotFound, \"no parent\"))?;\n    Ok(parent.symlink_metadata()?.is_dir())\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Validate mount paths in configuration at startup","Avoid paths whose parent segment could be a file or symlink","Clean up stale junctions/symlinks from prior setups"],"tags":["filesystem","windows","path-validation","mount"],"backgroundTag":"path-is-not-a-directory","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"}