atuinsh/atuin · error
could not determine home directory
Error message
could not determine home directory
What it means
home_dir() resolves the user home via directories::BaseDirs::new(), which on Unix reads $HOME. BaseDirs::new() returns None when no home can be determined (HOME unset or empty; on Windows a failed known-folder lookup). Because atuin's config dir, data dir, and database paths all hang off home_dir(), the expect crashes essentially any atuin command.
Source
Thrown at crates/atuin-common/src/utils.rs:107
if gitdir.parent().is_some() {
// if .git is a file (worktree), resolve to the main repo root
if let Some(main_repo) = resolve_git_worktree(&gitdir) {
return Some(main_repo);
}
return Some(gitdir);
}
None
}
// TODO: more reliable, more tested
// I don't want to use ProjectDirs, it puts config in awkward places on
// mac. Data too. Seems to be more intended for GUI apps.
pub fn home_dir() -> PathBuf {
directories::BaseDirs::new()
.map(|d| d.home_dir().to_path_buf())
.expect("could not determine home directory")
}
/// Read an environment variable that must be nonempty.
///
/// This function will never return an empty string: if the environment variable is set but empty,
/// [`None`] is returned.
pub fn env_nonempty(name: &str) -> Option<OsString> {
std::env::var_os(name).filter(|value| !value.is_empty())
}
pub fn config_dir() -> PathBuf {
let config_dir: PathBuf =
env_nonempty("XDG_CONFIG_HOME").map_or_else(|| home_dir().join(".config"), Into::into);
config_dir.join("atuin")
}
pub fn data_dir() -> PathBuf {
let data_dir: PathBuf = env_nonempty("XDG_DATA_HOME")View on GitHub (pinned to 202f6ad98e)
Solutions
- Set HOME explicitly for the service or container: systemd Environment="HOME=/var/lib/atuin", docker run -e HOME=/home/atuin
- Run atuin under a real user account whose passwd entry defines a home (check with getent passwd <user>)
- For systemd units prefer User= plus StateDirectory=/HomeDirectory= so the manager provisions the home
Example fix
# before (systemd unit) [Service] ExecStart=/usr/bin/atuin daemon # after [Service] User=atuin Environment=HOME=/var/lib/atuin StateDirectory=atuin ExecStart=/usr/bin/atuin daemon
Defensive patterns
Strategy: validation
Validate before calling
if cfg!(unix) && std::env::var_os("HOME").map_or(true, |h| h.is_empty()) {
eprintln!("HOME is not set; atuin needs it to locate its config and database");
std::process::exit(2);
} Try / catch
let home = std::panic::catch_unwind(atuin_common::utils::home_dir)
.expect("HOME must be set; fix the service environment instead of bypassing"); Prevention
- Always define HOME for services and containers that run atuin
- Check `getent passwd <user>` shows a home before running atuin as that user
- Add a fail-fast startup guard for missing HOME with a clear message
When it happens
Trigger: Any atuin invocation in a process whose environment lacks HOME: systemd services without Environment=, cron jobs, docker run without HOME set, env -i, or a service user with no usable passwd entry.
Common situations: Running the atuin daemon or server as a systemd unit without HOME; Docker images that set USER but not HOME; cron and CI runners; sudo with env_reset.
Related errors
- bug in list query. please report
- bug in search query. please report
- issue in stats previous query
- issue in stats next query
- issue in stats average query
AI-assisted analysis of atuinsh/atuin@202f6ad98e (2026-08-16).
Data as JSON: /api/errors/85f59324c8112c8b.
Report an issue: GitHub.