{"record":{"id":"09e04c6d3c825ea3","repo":"astrid-runtime/astrid","slug":"auto-created-mountpoint-is-not-empty","errorCode":null,"errorMessage":"auto-created mountpoint is not empty: {}","messagePattern":"auto-created mountpoint is not empty: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/astrid-storage-provider-fskit/src/main.rs","lineNumber":418,"sourceCode":"        errors.push(format!(\"registry: {error:#}\"));\n    }\n    if errors.is_empty()\n        && let Err(error) = cleanup_created_mountpoint(mountpoint, auto_created)\n    {\n        errors.push(format!(\"cleanup: {error:#}\"));\n    }\n    rollback_outcome(true, &errors)\n}\n\nfn cleanup_created_mountpoint(mountpoint: &Path, auto_created: bool) -> Result<()> {\n    if !auto_created {\n        return Ok(());\n    }\n    validate_unmounted_mountpoint(mountpoint)?;\n    let mut entries = std::fs::read_dir(mountpoint)\n        .with_context(|| format!(\"read auto-created mountpoint {}\", mountpoint.display()))?;\n    if entries.next().is_some() {\n        bail!(\n            \"auto-created mountpoint is not empty: {}\",\n            mountpoint.display()\n        );\n    }\n    std::fs::remove_dir(mountpoint)\n        .with_context(|| format!(\"remove auto-created mountpoint {}\", mountpoint.display()))\n}\n\nfn prepare_mountpoint(\n    requested: Option<PathBuf>,\n    view: &astrid_core::storage_provider::StorageProviderViewV1,\n) -> Result<(PathBuf, bool)> {\n    let mountpoint =\n        requested.map_or_else(|| default_mountpoint(std::env::var_os(\"HOME\"), view), Ok)?;\n    validate_mountpoint_layout(&mountpoint)?;\n    let existed = match std::fs::symlink_metadata(&mountpoint) {\n        Ok(_) => true,\n        Err(error) if error.kind() == std::io::ErrorKind::NotFound => false,","sourceCodeStart":400,"sourceCodeEnd":436,"githubUrl":"https://github.com/astrid-runtime/astrid/blob/affd8760f44190dbdfbec23403f4c4b642c33112/crates/astrid-storage-provider-fskit/src/main.rs#L400-L436","documentation":"When tearing down a mountpoint that this provider auto-created, cleanup_created_mountpoint() refuses to remove the directory if it is no longer empty after unmount — something wrote files into it (or a failed mount left debris), and deleting a non-empty directory could destroy user data.","triggerScenarios":"After unmount or rollback, validate_unmounted_mountpoint passed but read_dir still finds entries (entries.next().is_some()); triggered from mount, unmount, and rollback_after_native_failure for auto-created mountpoints only.","commonSituations":"User or another process placed files in ~/Astrid/<principal> while the fs was mounted or right after unmount; a crashed fskit daemon left journal files inside the mountpoint; race between two concurrent unmounts.","solutions":["Inspect the directory and move out any files you need, then re-run the unmount/cleanup.","Verify the fs was actually unmounted — if a hidden native mount still holds files, unmount it first.","Remove the directory manually only after confirming its contents are not needed.","Avoid pointing mounts at directories other processes write to; use a dedicated default mountpoint."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"fn mountpoint_is_empty(path: &Path) -> std::io::Result<bool> {\n    Ok(std::fs::read_dir(path)?.next().is_none())\n}\n// call before unmount/cleanup; if false, surface files to the user instead of removing","typeGuard":null,"tryCatchPattern":"if let Err(e) = cleanup_created_mountpoint(&mountpoint, auto_created) {\n    if e.to_string().contains(\"auto-created mountpoint is not empty\") {\n        // leave directory intact; notify user to inspect and remove manually\n    }\n}","preventionTips":["Never store user data directly in the mountpoint root that the provider auto-creates.","Avoid concurrent unmounts of the same path (use the registry as a lock).","Check for leftover daemon artifacts (journals, .DS_Store) before cleanup.","If you need the directory contents, move them out before unmounting."],"tags":["mountpoint","cleanup","safety-check"],"backgroundTag":"directory-not-found","analyzedSha":"affd8760f44190dbdfbec23403f4c4b642c33112","analyzedAt":"2026-09-09T21:28:12.402Z","contentChangedAt":"2026-09-09T21:28:12.402Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}