gitui-org/gitui · error · anyhow::Error

failed to find os config dir.

Error message

failed to find os config dir.

What it means

get_app_config_path() resolves gitui's config directory: dirs::config_dir() on all platforms except macOS, where gitui deliberately uses home_dir()/.config. The lookup returns None when the home directory cannot be determined (Linux: HOME unset and XDG_CONFIG_HOME unusable; macOS: HOME unset) or when XDG_CONFIG_HOME is set to a non-absolute path, which the dirs crate rejects. Because theme and key config live under this path, the anyhow error aborts startup.

Solutions

  1. Set HOME to an absolute path in the launching environment (export HOME=/home/<user>).
  2. Set XDG_CONFIG_HOME to an absolute path (export XDG_CONFIG_HOME=$HOME/.config) on Linux.
  3. On macOS, ensure HOME is exported in launchd agents and shells alike.
  4. For programmatic use, fall back to a bundled/default config when dirs::config_dir() is None rather than failing.

Example fix

# before
env -i /usr/bin/gitui   # bails: failed to find os config dir.
# after
env -i HOME=$HOME /usr/bin/gitui

// Rust: tolerate a missing config dir
// before
let cfg = get_app_config_path()?;
// after
let cfg = get_app_config_path().unwrap_or_else(|_| std::env::temp_dir().join("gitui"));
Defensive patterns

Strategy: validation

Validate before calling

# shell
[ -n "$HOME" ] && [ "${XDG_CONFIG_HOME:-""}" = "${XDG_CONFIG_HOME#/}" ] && echo 'XDG_CONFIG_HOME looks relative'

// Rust
dirs::config_dir().is_some()

Prevention

When it happens

Trigger: Running gitui with HOME unset/empty in cron, systemd, docker, or su contexts; exporting XDG_CONFIG_HOME with a relative path like .config; macOS with an unset HOME in a launchd agent.

Common situations: Service definitions and CI runners that spawn TUI tools without login environments; hardened containers; dotfiles that export relative XDG paths; ssh sessions into accounts with broken passwd entries.

Related errors


AI-assisted analysis of gitui-org/gitui@2fa693cb6e (2026-08-16). Data as JSON: /api/errors/b0c1b7ef406eb977. Report an issue: GitHub.

Appendix: source

Thrown at src/args.rs:235

		.ok_or_else(|| anyhow!("failed to find os cache dir."))?;

	path.push("gitui");
	fs::create_dir_all(&path).with_context(|| {
		format!(
			"failed to create cache directory: {}",
			path.display()
		)
	})?;
	Ok(path)
}

pub fn get_app_config_path() -> Result<PathBuf> {
	let mut path = if cfg!(target_os = "macos") {
		dirs::home_dir().map(|h| h.join(".config"))
	} else {
		dirs::config_dir()
	}
	.ok_or_else(|| anyhow!("failed to find os config dir."))?;

	path.push("gitui");
	Ok(path)
}

#[test]
fn verify_app() {
	app().debug_assert();
}

View on GitHub (pinned to 2fa693cb6e)