gitbutlerapp/gitbutler · error · anyhow::Error

Failed to determine home directory

Error message

Failed to determine home directory

What it means

`InstallerConfig::new_with_version` derives its install paths from `dirs::home_dir()`. When that call returns `None` — typically because `$HOME` is unset or empty on Linux, or user-profile directories are unavailable — config construction bails with this error before any platform detection happens.

Source

Thrown at crates/but-installer/src/config.rs:149

            bail!(
                "Too many arguments. Usage: but-installer [version|nightly] or GITBUTLER_VERSION=<version> but-installer"
            );
        }

        // Get version from CLI argument (takes precedence) or GITBUTLER_VERSION env var
        let version_string = args
            .get(1)
            .cloned()
            .or_else(|| env::var("GITBUTLER_VERSION").ok());

        let version_request = VersionRequest::from_string(version_string)?;
        Self::new_with_version(version_request)
    }

    /// Create a new installer config with an explicit version request
    pub(crate) fn new_with_version(version_request: VersionRequest) -> Result<Self> {
        let home_dir =
            dirs::home_dir().ok_or_else(|| anyhow!("Failed to determine home directory"))?;

        // Detect platform
        let os = env::consts::OS;
        let arch = env::consts::ARCH;

        let platform = match (os, arch) {
            ("macos", "aarch64") => "darwin-aarch64",
            ("macos", "x86_64") => "darwin-x86_64",
            ("linux", "aarch64") => "linux-aarch64",
            ("linux", "x86_64") => "linux-x86_64",
            (os, arch) => bail!("unsupported OS or architecture: {os} {arch}"),
        };

        Ok(Self {
            version_request,
            home_dir,
            platform: platform.to_string(),
        })

View on GitHub (pinned to caf1f223d3)

Solutions

  1. Set `HOME` to an absolute writable path (`export HOME=/home/user`) and rerun.
  2. For systemd units add `Environment="HOME=/root"` (or the service user's home); for cron, set HOME in the crontab or source a profile.
  3. Run the installer from a normal login shell where HOME is inherited.
  4. In containers, define a proper user home (`USER app` + `ENV HOME=/home/app`).

Example fix

# before (HOME unset, e.g. scrubbed CI or cron)
$ installer v1.2.3
error: Failed to determine home directory

# after
$ HOME=/home/ci installer v1.2.3
Defensive patterns

Strategy: validation

Validate before calling

// Run before creating the installer config
match std::env::var_os("HOME") {
    Some(h) if !h.is_empty() => {}
    _ => {
        eprintln!("HOME is not set; run from a login shell or export HOME.");
        std::process::exit(1);
    }
}

Try / catch

match InstallerConfig::new() {
    Ok(cfg) => cfg,
    Err(e) if e.to_string().contains("home directory") => {
        eprintln!("Set $HOME and retry (e.g. `export HOME=$PWD` in containers).");
        return Err(e);
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Creating an installer config in an environment where the home directory cannot be resolved: `HOME` unset in cron jobs, systemd services, `env -i` shells, minimal containers, or some CI runners that scrub the environment; sandboxed processes blocking profile lookups.

Common situations: Running the installer from a systemd unit or cron entry without `Environment="HOME=..."`; Docker images where the USER has no HOME defined; CI jobs with a sanitized env; tools that spawn processes with a minimal environment.

Related errors


AI-assisted analysis of gitbutlerapp/gitbutler@caf1f223d3 (2026-08-20). Data as JSON: /api/errors/f3f12654bc3d89fb. Report an issue: GitHub.