{"record":{"id":"b4ef2d634502e6de","repo":"astrid-runtime/astrid","slug":"mountpoint-must-be-absolute-b4ef2d","errorCode":null,"errorMessage":"mountpoint must be absolute","messagePattern":"mountpoint must be absolute","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/astrid-storage-provider-winfsp/src/main.rs","lineNumber":344,"sourceCode":"        {\n            Ok(false)\n        },\n        AdminResponseBody::Error(error) => {\n            bail!(\"kernel refused storage unmount authorization: {error}\")\n        },\n        _ => bail!(\"kernel returned an unexpected storage unmount response\"),\n    }\n}\n\n#[cfg(windows)]\nfn prepare_mountpoint(\n    requested: Option<PathBuf>,\n    view: &astrid_core::storage_provider::StorageProviderViewV1,\n) -> Result<(PathBuf, bool)> {\n    let _ = view;\n    let mountpoint = requested.map_or_else(first_free_drive, Ok)?;\n    if !mountpoint.is_absolute() {\n        bail!(\"mountpoint must be absolute\");\n    }\n    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()))?;","sourceCodeStart":326,"sourceCodeEnd":362,"githubUrl":"https://github.com/astrid-runtime/astrid/blob/affd8760f44190dbdfbec23403f4c4b642c33112/crates/astrid-storage-provider-winfsp/src/main.rs#L326-L362","documentation":"`prepare_mountpoint` validates the user-supplied mountpoint before handing it to WinFsp. On Windows, a mountpoint must be an absolute path (either a drive root like `E:\\` or a directory path); a relative path cannot be resolved reliably for filesystem mounting, so the provider rejects it immediately. When no path is supplied, `first_free_drive` picks an absolute drive automatically and this error cannot occur.","triggerScenarios":"Calling `mount` (or code that invokes `directory_mountpoint_leaf_is_reserved_for_winfsp`/`prepare_mountpoint`) with `requested = Some(relative_path)` such as `Some(PathBuf::from(\"mnt/data\"))` or `Some(PathBuf::from(\"..\\\\share\"))`.","commonSituations":"Passing a CLI-relative directory argument to a mount command; scripts that build mount paths from the current working directory; configuration files storing relative mount paths.","solutions":["Pass an absolute path (e.g. `C:\\mounts\\data` or a drive root `E:\\`) as the mountpoint","Convert the requested path to absolute in the caller with `std::fs::canonicalize` or by joining with a known base directory","Omit the mountpoint argument entirely to let the provider auto-select the first free drive letter"],"exampleFix":"// before\nlet requested = Some(PathBuf::from(\"mnt/storage\"));\nmount(provider, requested).await?;\n// after\nlet requested = Some(PathBuf::from(\"C:\\\\mnt\\\\storage\"));\nmount(provider, requested).await?;","handlingStrategy":"validation","validationCode":"// Rust caller-side pre-check\nfn ensure_absolute_mountpoint(p: &std::path::Path) -> Result<(), String> {\n    if p.is_absolute() { Ok(()) } else { Err(format!(\"mountpoint must be absolute: {}\", p.display())) }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always build mount paths from an absolute base directory","Use std::fs::canonicalize on user-supplied paths before passing them","Prefer omitting the mountpoint argument to let the provider pick a free drive"],"tags":["filesystem","windows","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"}