unicity-aos/aos-ce · error · std::io::Error
must be an absolute path
Error message
{variable} must be an absolute path What it means
validated_environment_root requires the root path to be absolute; a relative PathBuf triggers an InvalidInput io error "{variable} must be an absolute path", after which validate_path_entry performs further checks. Absolute paths are mandatory so runtime layout and private-directory creation cannot depend on the process's current working directory.
Solutions
- Prefix the value with "/" (or a drive root) in the environment: use an absolute path like /opt/myapp/runtime.
- Canonicalize in the launcher script, e.g. export MYAPP_ROOT="$(pwd)/data".
- Reject relative values at config-load time with a clear message before the process starts.
Example fix
// before export MYAPP_ROOT=data/runtime // after export MYAPP_ROOT=/var/lib/myapp/runtime
Defensive patterns
Strategy: validation
Validate before calling
fn require_absolute_env_path(name: &str) -> Result<PathBuf, String> {
let v = std::env::var_os(name).ok_or_else(|| format!("{name} not set"))?;
let p = PathBuf::from(&v);
if p.as_os_str().is_empty() { return Err(format!("{name} is empty")); }
if !p.is_absolute() { return Err(format!("{name} must be absolute, got {:?}", p)); }
Ok(p)
} Type guard
fn is_absolute_path(v: &OsStr) -> bool {
!v.is_empty() && Path::new(v).is_absolute()
} Try / catch
match validated_environment_root(root, "MYAPP_ROOT") {
Err(e) if e.to_string().contains("must be an absolute path") => {
eprintln!("fix MYAPP_ROOT in the unit file/script to start with /");
}
other => other?,
} Prevention
- Always write absolute paths into environment-based configuration, even in examples.
- In launch scripts derive absolute values: export MYAPP_ROOT="$(realpath data)".
- Lint deployment configs (systemd units, Dockerfiles) for relative path values in env assignments.
When it happens
Trigger: Setting a root environment variable to a relative path like "runtime" or "./data" and passing it through validated_environment_root.
Common situations: Writing VAR=data in a shell script assuming the daemon's cwd; copying an example config that used a relative path; launching the process from an unexpected working directory so a previously-working relative value now resolves elsewhere.
Understand the failure class
Background: "is not a valid" / "Invalid ... value" environment variable errors: how libraries validate env vars and what to do when they reject yours — this error's family across 48 libraries.
Related errors
- must not be empty
- bundled executable must have a parent directory
- cannot construct the bundled runtime PATH
- cannot contain a platform PATH separator
- canonical document exceeds bound
AI-assisted analysis of unicity-aos/aos-ce@f6f22024fb (2026-09-13).
Data as JSON: /api/errors/d121637c0228133d.
Report an issue: GitHub.
Appendix: source
Thrown at crates/unicity-aos-bootstrap/src/lib.rs:100
}
fn from_environment_root(root: OsString, variable: &str) -> io::Result<Self> {
Ok(Self::from_root(Self::validated_environment_root(
root, variable,
)?))
}
fn validated_environment_root(root: OsString, variable: &str) -> io::Result<PathBuf> {
if root.is_empty() {
return Err(io::Error::new(
io::ErrorKind::InvalidInput,
format!("{variable} must not be empty"),
));
}
let root = PathBuf::from(root);
if !root.is_absolute() {
return Err(io::Error::new(
io::ErrorKind::InvalidInput,
format!("{variable} must be an absolute path"),
));
}
validate_path_entry(&root, variable)?;
Ok(root)
}
/// Build an AOS home from an explicit root, useful for embedding and tests.
#[must_use]
pub fn from_root(root: impl Into<PathBuf>) -> Self {
Self { root: root.into() }
}
/// The product-owned AOS root.
#[must_use]
pub fn root(&self) -> &Path {
&self.rootView on GitHub (pinned to f6f22024fb)