astrid-runtime/astrid · error
mountpoint parent is not a directory: {}
Error message
mountpoint parent is not a directory: {} What it means
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.
Source
Thrown at crates/astrid-storage-provider-winfsp/src/main.rs:364
if is_drive_target(&mountpoint) {
if std::fs::metadata(&mountpoint).is_ok() {
bail!(
"Windows drive target is already in use: {}",
mountpoint.display()
);
}
return Ok((mountpoint, false));
}
let parent = mountpoint
.parent()
.context("WinFsp directory mountpoint has no parent")?;
std::fs::create_dir_all(parent)
.with_context(|| format!("create mountpoint parent {}", parent.display()))?;
astrid_core::platform_fs::verify_no_redirects(parent)
.with_context(|| format!("reject redirected mountpoint parent {}", parent.display()))?;
if !std::fs::symlink_metadata(parent)?.is_dir() {
bail!("mountpoint parent is not a directory: {}", parent.display());
}
match std::fs::symlink_metadata(&mountpoint) {
Err(error) if error.kind() == std::io::ErrorKind::NotFound => {},
Err(error) => {
return Err(error)
.with_context(|| format!("inspect mountpoint {}", mountpoint.display()));
},
Ok(_) => bail!(
"WinFsp directory mountpoint must not already exist: {}",
mountpoint.display()
),
}
// WinFsp creates and owns directory mountpoint leaves. Treat the leaf as
// provider-created so failure and unmount cleanup remain idempotent.
Ok((mountpoint, true))
}
#[cfg(not(windows))]View on GitHub (pinned to affd8760f4)
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
Example fix
// before: parent is a file
mount(provider, Some(PathBuf::from("C:\\notes.txt\\storage"))).await?;
// after: parent is a directory
std::fs::create_dir_all("C:\\mounts")?;
mount(provider, Some(PathBuf::from("C:\\mounts\\storage"))).await?; Defensive patterns
Strategy: validation
Validate before calling
// Verify parent is a real directory before mounting
fn parent_is_dir(mountpoint: &std::path::Path) -> std::io::Result<bool> {
let parent = mountpoint.parent().ok_or_else(|| std::io::Error::new(std::io::ErrorKind::NotFound, "no parent"))?;
Ok(parent.symlink_metadata()?.is_dir())
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- mountpoint must be absolute
- mountpoint must be absolute
- mountpoint must be below a parent directory
- WinFsp directory mountpoint must not already exist: {}
- no free Windows drive target is available; specify a directo
AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09).
Data as JSON: /api/errors/e77366835c49e33f.
Report an issue: GitHub.