astrid-runtime/astrid · error

mountpoint is not empty: {}

Error message

mountpoint is not empty: {}

What it means

validate_unmounted_mountpoint() performs full safety validation (layout, ancestors, no symlink redirects, private-directory permissions) and finally requires the directory to be empty; if read_dir yields any entry, the path is either still mounted, mid-teardown, or contains foreign files, so the provider refuses to proceed rather than clobber data.

Source

Thrown at crates/astrid-storage-provider-fskit/src/main.rs:480

    let leaf = match view {
        astrid_core::storage_provider::StorageProviderViewV1::Principal(principal) => {
            principal.to_string()
        },
        astrid_core::storage_provider::StorageProviderViewV1::Fleet(fleet) => fleet.to_string(),
        astrid_core::storage_provider::StorageProviderViewV1::Admin => "system".to_owned(),
    };
    Ok(home.join("Astrid").join(leaf))
}

fn validate_unmounted_mountpoint(mountpoint: &Path) -> Result<()> {
    validate_mountpoint_layout(mountpoint)?;
    validate_mountpoint_ancestors(mountpoint)?;
    astrid_core::platform_fs::verify_no_redirects(mountpoint)
        .with_context(|| format!("reject redirected mountpoint {}", mountpoint.display()))?;
    astrid_core::platform_fs::validate_private_directory(mountpoint)
        .with_context(|| format!("reject unsafe mountpoint {}", mountpoint.display()))?;
    if std::fs::read_dir(mountpoint)?.next().is_some() {
        bail!("mountpoint is not empty: {}", mountpoint.display());
    }
    Ok(())
}

fn validate_mounted_mountpoint(mountpoint: &Path) -> Result<()> {
    validate_mountpoint_layout(mountpoint)?;
    validate_mountpoint_ancestors(mountpoint)?;
    astrid_core::platform_fs::verify_no_redirects(mountpoint)
        .with_context(|| format!("reject redirected mountpoint {}", mountpoint.display()))?;
    if !native_mount_is_active(mountpoint)? {
        bail!(
            "macOS did not activate an astridfs mount at {}",
            mountpoint.display()
        );
    }
    Ok(())
}

View on GitHub (pinned to affd8760f4)

Solutions

  1. Confirm nothing is mounted there (mount | grep the path; native_mount_is_active) and unmount if needed.
  2. List the directory (ls -la) and remove or move out leftover files, then retry the operation.
  3. If .DS_Store/fseventsd-style debris keeps appearing on macOS, clean it after each unmount or use a dedicated mountpoint.
  4. Ensure only one provider instance manages this mountpoint to avoid concurrent repopulation.
Defensive patterns

Strategy: validation

Validate before calling

fn assert_empty_unmounted(path: &Path) -> anyhow::Result<()> {
    if std::fs::read_dir(path)?.next().is_some() {
        anyhow::bail!("{} not empty", path.display());
    }
    Ok(())
}
// run before mount requests targeting an existing directory

Try / catch

if let Err(e) = validate_unmounted_mountpoint(&mountpoint) {
    if e.to_string().contains("mountpoint is not empty") {
        // check for active mount, clean debris (.DS_Store, fseventsd), then retry
    }
}

Prevention

When it happens

Trigger: Called from unmount (after native unmount), cleanup_created_mountpoint, prepare_mountpoint (before mount on an existing dir), and tests; fires when any file, directory, or dotfile exists in the mountpoint — commonly because the native unmount did not actually take effect or something repopulated the directory.

Common situations: Leftover .DS_Store or fseventsd files on macOS after unmount; user data saved into the folder while mounted; a second mount/daemon still holding the path; hidden files from a previous failed run.

Related errors


AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09). Data as JSON: /api/errors/56c525d8b63d126b. Report an issue: GitHub.