{"record":{"id":"74e7d059d7413a6c","repo":"astrid-runtime/astrid","slug":"mountpoint-is-not-a-directory","errorCode":null,"errorMessage":"mountpoint is not a directory: {}","messagePattern":"mountpoint is not a directory: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/astrid-storage-provider-fuse/src/mountpoint.rs","lineNumber":39,"sourceCode":"        };\n        std::env::var_os(\"HOME\")\n            .map_or_else(|| PathBuf::from(\"/tmp\"), PathBuf::from)\n            .join(\"Astrid\")\n            .join(leaf)\n    });\n    if !requested.is_absolute() {\n        bail!(\"mountpoint must be absolute\");\n    }\n    let existed = requested.symlink_metadata().is_ok();\n    if !existed {\n        std::fs::create_dir_all(&requested)\n            .with_context(|| format!(\"create mountpoint {}\", requested.display()))?;\n    }\n    astrid_core::platform_fs::verify_no_redirects(&requested)\n        .with_context(|| format!(\"reject redirected mountpoint {}\", requested.display()))?;\n    let metadata = std::fs::symlink_metadata(&requested)?;\n    if !metadata.is_dir() {\n        bail!(\"mountpoint is not a directory: {}\", requested.display());\n    }\n    let expected_uid = u32::from(getuid());\n    if metadata.uid() != expected_uid {\n        bail!(\n            \"mountpoint must be owned by the current OS user: {}\",\n            requested.display()\n        );\n    }\n    let mode = metadata.permissions().mode();\n    if !existed {\n        std::fs::set_permissions(&requested, Permissions::from_mode(0o700))?;\n    } else if mode & 0o077 != 0 {\n        bail!(\"mountpoint must be owner-private: {}\", requested.display());\n    }\n    if std::fs::read_dir(&requested)?.next().is_some() {\n        bail!(\"mountpoint is not empty: {}\", requested.display());\n    }\n    let canonical = requested","sourceCodeStart":21,"sourceCodeEnd":57,"githubUrl":"https://github.com/astrid-runtime/astrid/blob/affd8760f44190dbdfbec23403f4c4b642c33112/crates/astrid-storage-provider-fuse/src/mountpoint.rs#L21-L57","documentation":"After ensuring the mountpoint exists and contains no symlink redirects, prepare_mountpoint checks that its metadata is a directory. A file, symlink-to-file, or other non-directory at that path triggers \"mountpoint is not a directory: {path}\" (crates/astrid-storage-provider-fuse/src/mountpoint.rs:39).","triggerScenarios":"A regular file or symlink exists at the requested mountpoint path, so symlink_metadata succeeds but is_dir() is false when prepare_mountpoint runs.","commonSituations":"A previous failed run left a stray file at the mountpoint path; a user created a file where the mount was expected; a symlink pointing to a non-directory target; typo in the mountpoint path colliding with an existing file.","solutions":["Remove or rename the file/symlink occupying the mountpoint path, then retry the mount","Choose a different, empty directory path for the mountpoint","Inspect the path with ls -la to confirm what is there before mounting"],"exampleFix":"// before\n// /home/user/Astrid/vol exists as a regular file\nprepare_mountpoint(Path::new(\"/home/user/Astrid/vol\"))?; // bails: not a directory\n// after\nstd::fs::remove_file(\"/home/user/Astrid/vol\")?; // clear the stray file\nprepare_mountpoint(Path::new(\"/home/user/Astrid/vol\"))?; // creates the dir","handlingStrategy":"validation","validationCode":"let md = std::fs::symlink_metadata(&mp)?; if !md.is_dir() { eprintln!(\"{} is not a directory\", mp.display()); }","typeGuard":"fn is_directory(p: &std::path::Path) -> bool { std::fs::symlink_metadata(p).map(|m| m.is_dir()).unwrap_or(false) }","tryCatchPattern":"match prepare_mountpoint(&mp) { Err(e) if e.to_string().starts_with(\"mountpoint is not a directory\") => { clear_path(&mp)?; prepare_mountpoint(&mp)? }, r => r? }","preventionTips":["Inspect the mountpoint path before mounting","Remove stray files/symlinks left by failed runs","Use dedicated, empty directories as mountpoints"],"tags":["mountpoint","filesystem","validation","path"],"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"}