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

  1. Set AOS_HOME explicitly to the desired state directory and retry.
  2. Ensure USERPROFILE is present in the environment (it normally points to C:\Users\<user>).
  3. If launching the process yourself, pass the parent environment or at minimum USERPROFILE instead of an empty env map.
  4. 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

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


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)