astrid-runtime/astrid · error

HOME is required to choose a private mountpoint

Error message

HOME is required to choose a private mountpoint

What it means

default_mountpoint derives a private mountpoint under the user's home directory; when the HOME environment variable is absent (home == None) there is no safe private location to choose, so it fails. This guard also ensures mountpoints are not placed in unpredictable shared locations.

Solutions

  1. Set the HOME environment variable before running the provider (export HOME=/Users/you or /home/you).
  2. In a service unit, set Environment=HOME=/var/lib/astrid or pass an explicit mountpoint instead of relying on the default.
  3. Ensure HOME is absolute, since a relative HOME fails the next check.

Example fix

// before (service unit with no env)
ExecStart=/usr/local/bin/astrid-storage-provider-fskit mount
// after
Environment=HOME=/var/lib/astrid
ExecStart=/usr/local/bin/astrid-storage-provider-fskit mount
Defensive patterns

Strategy: validation

Validate before calling

if !process.env.HOME || !path.isAbsolute(process.env.HOME) {
  throw new Error("HOME must be set and absolute before mounting");
}

Type guard

fn has_absolute_home(env: &std::collections::HashMap<String, String>) -> Option<&str> {
    env.get("HOME").filter(|h| std::path::Path::new(h).is_absolute()).map(|s| s.as_str())
}

Try / catch

match default_mountpoint(std::env::var_os("HOME"), &view) {
    Ok(mp) => mount_at(mp).await,
    Err(e) => eprintln!("cannot choose mountpoint: {e:#}; set HOME explicitly"),
}

Prevention

When it happens

Trigger: Calling prepare_mountpoint -> default_mountpoint with home: Option<OsString> == None, typically because the HOME env var is not set in the process environment.

Common situations: Running the fskit provider from a systemd unit or cron job with a minimal environment; launching via SSH with env resetting disabled; running inside a container without HOME set.

Understand the failure class

Background: "environment variable is not set" and "Missing keys in environment" errors: what missing required env var messages mean and how to fix them — this error's family across 28 libraries.

Related errors


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

Appendix: source

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

        },
    };
    if existed {
        validate_unmounted_mountpoint(&mountpoint)?;
    } else {
        astrid_core::platform_fs::ensure_private_directory(&mountpoint)
            .with_context(|| format!("create private mountpoint {}", mountpoint.display()))?;
        validate_unmounted_mountpoint(&mountpoint)?;
    }
    Ok((mountpoint, !existed))
}

fn default_mountpoint(
    home: Option<std::ffi::OsString>,
    view: &astrid_core::storage_provider::StorageProviderViewV1,
) -> Result<PathBuf> {
    let home = home
        .map(PathBuf::from)
        .ok_or_else(|| anyhow::anyhow!("HOME is required to choose a private mountpoint"))?;
    if !home.is_absolute() {
        bail!("HOME must be absolute to choose a private mountpoint");
    }
    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()))?;

View on GitHub (pinned to affd8760f4)