unicity-aos/aos-ce · error · std::io::Error
AOS_HOME, USERPROFILE, and HOMEDRIVE/HOMEPATH are all unset
Error message
AOS_HOME, USERPROFILE, and HOMEDRIVE/HOMEPATH are all unset
What it means
The Windows branch of default_home (crates/unicity-aos-bootstrap/src/lib.rs:600) resolves the AOS home directory from AOS_HOME first, then USERPROFILE, then HOMEDRIVE+HOMEPATH; if none are set it throws this io::Error (NotFound). The library needs a home directory to build its default state layout and cannot proceed without one.
Solutions
- Set AOS_HOME explicitly to the desired state directory and retry.
- Ensure USERPROFILE is present in the environment (it normally points to C:\Users\<user>).
- If launching the process yourself, pass the parent environment or at minimum USERPROFILE instead of an empty env map.
- As a last resort set both HOMEDRIVE (e.g. 'C:') and HOMEPATH (e.g. '\Users\me').
Example fix
// before: spawned with cleared env
Command::new("aos").env_clear().status()
// after
Command::new("aos").env("AOS_HOME", "C:\\aos-state").status() Defensive patterns
Strategy: fallback
Validate before calling
let home = std::env::var_os("AOS_HOME")
.or_else(|| std::env::var_os("USERPROFILE"))
.or_else(|| -> Option<std::ffi::OsString> {
Some(std::ffi::OsString::from(format!(
"{}{}",
std::env::var("HOMEDRIVE").ok()?,
std::env::var("HOMEPATH").ok()?)))
});
if home.is_none() {
return Err("set AOS_HOME or USERPROFILE before running".into());
} Try / catch
match result {
Err(e) if e.kind() == std::io::ErrorKind::NotFound && e.to_string().contains("HOMEDRIVE/HOMEPATH") => {
eprintln!("no home directory in environment; set AOS_HOME=<dir> and retry");
}
other => other?,
} Prevention
- Set AOS_HOME explicitly in service definitions, scheduled tasks, and containers.
- When spawning child processes, inherit the parent environment instead of env_clear().
- For Windows services, configure the account profile or add Environment entries in the service/CI config.
When it happens
Trigger: Calling resolve_with or default_legacy_runtime_home on Windows when AOS_HOME, USERPROFILE, and HOMEDRIVE/HOMEPATH are all absent from the process environment — e.g. running under a stripped-down service account, a scheduled task with a minimal environment, or a container where these vars were never set.
Common situations: Windows services and some CI runners run with USERPROFILE unset; custom process launches (CreateProcess / std::process::Command with cleared env) drop the variables; headless/containerized Windows builds.
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 and HOME are both unset
- cannot contain a platform PATH separator
- canonical document exceeds bound
- Unicity AOS health service must bind to 127.0.0.1
- must not be empty
AI-assisted analysis of unicity-aos/aos-ce@f6f22024fb (2026-09-13).
Data as JSON: /api/errors/65cc747ad3708071.
Report an issue: GitHub.
Appendix: source
Thrown at crates/unicity-aos-bootstrap/src/lib.rs:610
fs::set_permissions(path, fs::Permissions::from_mode(0o600))?;
}
#[cfg(not(unix))]
let _ = path;
Ok(())
}
#[cfg(windows)]
fn default_home<F>(get: &F) -> io::Result<OsString>
where
F: Fn(&str) -> Option<OsString>,
{
if let Some(home) = get("USERPROFILE") {
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"View on GitHub (pinned to f6f22024fb)