{"record":{"id":"f3f12654bc3d89fb","repo":"gitbutlerapp/gitbutler","slug":"failed-to-determine-home-directory","errorCode":null,"errorMessage":"Failed to determine home directory","messagePattern":"Failed to determine home directory","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/but-installer/src/config.rs","lineNumber":149,"sourceCode":"            bail!(\n                \"Too many arguments. Usage: but-installer [version|nightly] or GITBUTLER_VERSION=<version> but-installer\"\n            );\n        }\n\n        // Get version from CLI argument (takes precedence) or GITBUTLER_VERSION env var\n        let version_string = args\n            .get(1)\n            .cloned()\n            .or_else(|| env::var(\"GITBUTLER_VERSION\").ok());\n\n        let version_request = VersionRequest::from_string(version_string)?;\n        Self::new_with_version(version_request)\n    }\n\n    /// Create a new installer config with an explicit version request\n    pub(crate) fn new_with_version(version_request: VersionRequest) -> Result<Self> {\n        let home_dir =\n            dirs::home_dir().ok_or_else(|| anyhow!(\"Failed to determine home directory\"))?;\n\n        // Detect platform\n        let os = env::consts::OS;\n        let arch = env::consts::ARCH;\n\n        let platform = match (os, arch) {\n            (\"macos\", \"aarch64\") => \"darwin-aarch64\",\n            (\"macos\", \"x86_64\") => \"darwin-x86_64\",\n            (\"linux\", \"aarch64\") => \"linux-aarch64\",\n            (\"linux\", \"x86_64\") => \"linux-x86_64\",\n            (os, arch) => bail!(\"unsupported OS or architecture: {os} {arch}\"),\n        };\n\n        Ok(Self {\n            version_request,\n            home_dir,\n            platform: platform.to_string(),\n        })","sourceCodeStart":131,"sourceCodeEnd":167,"githubUrl":"https://github.com/gitbutlerapp/gitbutler/blob/caf1f223d3cfb94488c9198ad34487c6006c648f/crates/but-installer/src/config.rs#L131-L167","documentation":"`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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Set `HOME` to an absolute writable path (`export HOME=/home/user`) and rerun.","For systemd units add `Environment=\"HOME=/root\"` (or the service user's home); for cron, set HOME in the crontab or source a profile.","Run the installer from a normal login shell where HOME is inherited.","In containers, define a proper user home (`USER app` + `ENV HOME=/home/app`)."],"exampleFix":"# before (HOME unset, e.g. scrubbed CI or cron)\n$ installer v1.2.3\nerror: Failed to determine home directory\n\n# after\n$ HOME=/home/ci installer v1.2.3","handlingStrategy":"validation","validationCode":"// Run before creating the installer config\nmatch std::env::var_os(\"HOME\") {\n    Some(h) if !h.is_empty() => {}\n    _ => {\n        eprintln!(\"HOME is not set; run from a login shell or export HOME.\");\n        std::process::exit(1);\n    }\n}","typeGuard":null,"tryCatchPattern":"match InstallerConfig::new() {\n    Ok(cfg) => cfg,\n    Err(e) if e.to_string().contains(\"home directory\") => {\n        eprintln!(\"Set $HOME and retry (e.g. `export HOME=$PWD` in containers).\");\n        return Err(e);\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Always define HOME in systemd units, cron entries, and container images that run installers.","Run installers from login shells so HOME is inherited.","Fail fast on a missing HOME at startup with an actionable message instead of deep inside config building."],"tags":["rust","installer","dirs","home-directory","environment","linux","containers","systemd"],"backgroundTag":"home-directory-not-found","analyzedSha":"caf1f223d3cfb94488c9198ad34487c6006c648f","analyzedAt":"2026-08-20T07:55:40.983Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}