astrid-runtime/astrid · error

native_mount_failure_message(classify_native_mount_failure(o…

Error message

native_mount_failure_message(classify_native_mount_failure(output.status.code(), &stderr, &stdout))

What it means

On macOS, native_mount invokes the FSKit mount helper as a subprocess; when it exits non-zero the error message embeds a classification of the failure (derived from exit code, stderr, and stdout) via classify_native_mount_failure. This means the OS-level mount syscall/helper refused the mount — the cause is reported inside the message, e.g. authorization, busy resource, or unknown filesystem.

Solutions

  1. Read the classified cause embedded in the error message and address that specific issue (authorization, busy, not-found)
  2. Verify the mountpoint is not already mounted: mount | grep <mountpoint>
  3. Re-register/rebuild the FSKit extension and confirm it is enabled in System Settings > Login Items & Extensions
  4. Re-run with the helper's stderr captured to see the raw OS error

Example fix

// before
native_mount(&lease, &mountpoint).await?; // fails, message shows classification
// after
match native_mount(&lease, &mountpoint).await {
    Err(e) if e.to_string().contains("busy") => { unmount_stale(&mountpoint)?; native_mount(&lease, &mountpoint).await? }
    r => r?,
}
Defensive patterns

Strategy: try-catch

Validate before calling

// pre-flight: ensure helper exists and mountpoint is free
if !std::path::Path::new("/sbin/mount_fskit").exists() { /* helper missing */ }
let active = native_mount_is_active(&mountpoint).unwrap_or(false);
if active { return Err(anyhow::anyhow!("already mounted")); }

Try / catch

match native_mount(&lease, &mp).await {
    Err(e) => {
        eprintln!("fskit mount failed: {e:#}"); // classified cause is in the message
        // handle authorization / busy / not-found per classification
    }
    Ok(()) => {}
}

Prevention

When it happens

Trigger: Calling mount (or actual_fskit_mount_and_unmount_round_trip) on macOS when the helper binary exits non-zero: missing entitlement/authorization, mountpoint already mounted, invalid lease/resource path, or FSKit extension not registered.

Common situations: Running without Full Disk Access or the required mount entitlement; attempting to mount the same volume twice; macOS security policies blocking FSKit extensions in CI VMs; stale registry record pointing at a gone resource.

Related errors


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

Appendix: source

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

        bail!("mountpoint must be below a parent directory");
    }
    Ok(())
}

#[cfg(target_os = "macos")]
pub(crate) async fn native_mount(lease: &StorageMountLeaseV1, mountpoint: &Path) -> Result<()> {
    let output = tokio::process::Command::new("/sbin/mount")
        .arg("-t")
        .arg("astridfs")
        .arg(&lease.resource_path)
        .arg(mountpoint)
        .output()
        .await
        .context("invoke macOS FSKit mount")?;
    if !output.status.success() {
        let stderr = String::from_utf8_lossy(&output.stderr);
        let stdout = String::from_utf8_lossy(&output.stdout);
        bail!(native_mount_failure_message(
            &classify_native_mount_failure(output.status.code(), &stderr, &stdout,)
        ));
    }
    Ok(())
}

#[cfg(not(target_os = "macos"))]
pub(crate) fn native_mount(
    lease: &StorageMountLeaseV1,
    mountpoint: &Path,
) -> std::future::Ready<Result<()>> {
    let _ = (lease, mountpoint);
    std::future::ready(Err(anyhow::anyhow!(
        "the FSKit provider is available only on macOS"
    )))
}

#[cfg(target_os = "macos")]

View on GitHub (pinned to affd8760f4)