{"record":{"id":"342c9e29b0e69a2a","repo":"astrid-runtime/astrid","slug":"winfsp-directory-mountpoint-must-not-already-exist","errorCode":null,"errorMessage":"WinFsp directory mountpoint must not already exist: {}","messagePattern":"WinFsp directory mountpoint must not already exist: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/astrid-storage-provider-winfsp/src/main.rs","lineNumber":372,"sourceCode":"    }\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))]\nfn prepare_mountpoint(\n    _requested: Option<PathBuf>,\n    _view: &astrid_core::storage_provider::StorageProviderViewV1,\n) -> Result<(PathBuf, bool)> {\n    bail!(\"the WinFsp provider is available only on Windows\")\n}\n\n#[cfg(windows)]","sourceCodeStart":354,"sourceCodeEnd":390,"githubUrl":"https://github.com/astrid-runtime/astrid/blob/affd8760f44190dbdfbec23403f4c4b642c33112/crates/astrid-storage-provider-winfsp/src/main.rs#L354-L390","documentation":"WinFsp creates and owns the directory mountpoint leaf itself; the provider therefore requires that the final leaf path does NOT already exist. `prepare_mountpoint` checks `symlink_metadata` on the mountpoint and bails if anything (file, directory, or symlink) is present, so cleanup on failure/unmount stays idempotent and WinFsp can create the leaf cleanly.","triggerScenarios":"Calling `mount` with a directory mountpoint path where the leaf already exists — e.g. a previous mount crashed without cleanup, the user pre-created the folder, or a stale empty directory was left behind.","commonSituations":"Re-mounting after an unclean shutdown or provider crash that left the empty leaf directory; scripts that `mkdir` the mountpoint first out of habit from other FUSE-like tools; leftover directories from an uninstalled setup.","solutions":["Delete the existing empty directory at the mountpoint path, then retry the mount","Choose a different mountpoint leaf path","If the leftover is a live mount, unmount it properly first via the provider's `unmount`"],"exampleFix":"// before\nstd::fs::create_dir_all(\"C:\\\\mounts\\\\storage\")?; // pre-creating the leaf breaks WinFsp\nmount(provider, Some(PathBuf::from(\"C:\\\\mounts\\\\storage\"))).await?;\n// after: let WinFsp create the leaf\nmount(provider, Some(PathBuf::from(\"C:\\\\mounts\\\\storage\"))).await?;","handlingStrategy":"validation","validationCode":"// Ensure the mountpoint leaf does not exist before mounting\nfn leaf_free(mountpoint: &std::path::Path) -> bool {\n    matches!(std::fs::symlink_metadata(mountpoint), Err(e) if e.kind() == std::io::ErrorKind::NotFound)\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never pre-create the mountpoint leaf directory — WinFsp owns it","Update old scripts that mkdir the mount target before mounting","After unclean shutdowns, remove leftover empty leaf directories before remounting"],"tags":["filesystem","windows","file-already-exists","mount"],"backgroundTag":"file-already-exists","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"}