unicity-aos/aos-ce · error · std::io::Error
AOS_HOME and HOME are both unset
Error message
AOS_HOME and HOME are both unset
What it means
The non-Windows branch of default_home (crates/unicity-aos-bootstrap/src/lib.rs:617) resolves the AOS home directory from AOS_HOME first, then falls back to HOME; if HOME is also unset it throws this io::Error (NotFound). The library cannot determine where to place its default state/runtime layout.
Solutions
- Set AOS_HOME explicitly to the state directory and retry.
- Ensure HOME is exported in the execution environment (e.g. HOME=/root or the user's home).
- In systemd, add Environment="HOME=/var/lib/<user>" to the unit or use EnvironmentFile.
- If spawning the process yourself, inherit the parent environment rather than env_clear().
Example fix
// before
Command::new("aos").env_clear().status()
// after
Command::new("aos").env("AOS_HOME", "/var/lib/aos").status() Defensive patterns
Strategy: fallback
Validate before calling
let home = std::env::var_os("AOS_HOME").or_else(|| std::env::var_os("HOME"));
if home.is_none() {
return Err("set AOS_HOME or HOME before running".into());
} Try / catch
match result {
Err(e) if e.kind() == std::io::ErrorKind::NotFound && e.to_string().contains("AOS_HOME and HOME are both unset") => {
eprintln!("no home directory in environment; set AOS_HOME=<dir> or HOME=<dir> and retry");
}
other => other?,
} Prevention
- Set AOS_HOME explicitly in systemd units, cron jobs, and container entrypoints.
- Verify containers/users have a home directory in /etc/passwd, or export HOME in the entrypoint.
- Avoid env_clear() when spawning; inherit or explicitly pass HOME.
When it happens
Trigger: Calling resolve_with or default_legacy_runtime_home on Linux/macOS when neither AOS_HOME nor HOME is set in the process environment — e.g. a daemon launched by systemd/cron with a minimal env, a container running as a user with no passwd entry, or a process spawned with env_clear().
Common situations: systemd units with 'Environment=' stripped; Docker images running as non-root users created without a home directory; CI jobs with sanitized environments; setuid or service wrappers that scrub HOME.
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
- AOS_HOME, USERPROFILE, and HOMEDRIVE/HOMEPATH are all unset
- bundled executable is not executable at
- cannot contain a platform PATH separator
- canonical document exceeds bound
- Unicity AOS health service must bind to 127.0.0.1
AI-assisted analysis of unicity-aos/aos-ce@f6f22024fb (2026-09-13).
Data as JSON: /api/errors/aac90af503ddfbe3.
Report an issue: GitHub.
Appendix: source
Thrown at crates/unicity-aos-bootstrap/src/lib.rs:623
return Ok(home);
}
match (get("HOMEDRIVE"), get("HOMEPATH")) {
(Some(drive), Some(path)) => Ok(PathBuf::from(drive).join(path).into_os_string()),
_ => Err(io::Error::new(
io::ErrorKind::NotFound,
"AOS_HOME, USERPROFILE, and HOMEDRIVE/HOMEPATH are all unset",
)),
}
}
#[cfg(not(windows))]
fn default_home<F>(get: &F) -> io::Result<OsString>
where
F: Fn(&str) -> Option<OsString>,
{
get("HOME")
.ok_or_else(|| io::Error::new(io::ErrorKind::NotFound, "AOS_HOME and HOME are both unset"))
}
#[cfg(windows)]
const fn default_home_name() -> &'static str {
"USERPROFILE"
}
#[cfg(not(windows))]
const fn default_home_name() -> &'static str {
"HOME"
}
const fn runtime_binary_name() -> &'static str {
RUNTIME_EXECUTABLE_NAMES[0]
}
const fn runtime_daemon_binary_name() -> &'static str {
RUNTIME_EXECUTABLE_NAMES[1]View on GitHub (pinned to f6f22024fb)