unicity-aos/aos-ce · error · io::Error
bundled product runtime path must have a parent
Error message
bundled product runtime path must have a parent
What it means
In checked_target_path, when the bundled product runtime target path does not exist (NotFound), the code canonicalizes the parent and rejoins the final component. If the path has no parent (e.g. a bare root-relative component like Path::new("runtime")), parent() returns None and this InvalidInput error is thrown. It guards the NotFound repair path from operating on degenerate paths.
Solutions
- Pass an absolute target path that includes a real parent directory (e.g. /opt/product/runtime)
- Check target.parent().is_some() and target.file_name().is_some() before invoking migrate_runtime
- If composing the path, join the final runtime directory onto an existing base directory
Example fix
// before
let target = Path::new("runtime");
migrate_runtime(target, ...)?;
// after
let target = Path::new("/opt/product/runtime");
migrate_runtime(target, ...)?; Defensive patterns
Strategy: validation
Validate before calling
fn target_path_ok(target: &std::path::Path) -> bool {
target.parent().is_some() && target.file_name().is_some()
} Type guard
fn has_parent_and_name(p: &std::path::Path) -> Option<(std::path::PathBuf, std::ffi::OsString)> {
Some((p.parent()?.to_path_buf(), p.file_name()?.to_os_string()))
} Try / catch
match migrate_runtime(&target, ...) {
Ok(()) => {},
Err(e) if e.to_string().contains("must have a parent") =>
eprintln!("use an absolute target path with a real parent directory"),
Err(e) => return Err(e),
} Prevention
- Always pass fully qualified absolute paths as migration targets
- Reject single-component or root paths in your CLI/config layer
- Join the runtime directory name onto an existing base directory when composing targets
When it happens
Trigger: Calling migrate_runtime with a bundled product runtime target path that has no parent directory component, such as a relative single-component path or a bare root path.
Common situations: Passing a target like "runtime" or "/" instead of a fully qualified installation path; constructing the target programmatically with a missing base directory.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- bundled product runtime path must have a final component
- must be an absolute path
- bundled executable must have a parent directory
- cannot construct the bundled runtime PATH
- cannot contain a platform PATH separator
AI-assisted analysis of unicity-aos/aos-ce@f6f22024fb (2026-09-13).
Data as JSON: /api/errors/3fb0abd41d7958f0.
Report an issue: GitHub.
Appendix: source
Thrown at crates/unicity-aos-bootstrap/src/migration.rs:542
let _ = fs::read(&pid)?;
}
Err(error) if error.kind() == io::ErrorKind::NotFound => {}
Err(error) => return Err(error),
}
Ok(())
}
fn checked_target_path(path: &Path) -> io::Result<PathBuf> {
match fs::symlink_metadata(path) {
Ok(metadata) => {
if metadata.file_type().is_symlink() || !metadata.is_dir() {
return invalid("bundled product runtime must be a real directory");
}
path.canonicalize()
}
Err(error) if error.kind() == io::ErrorKind::NotFound => {
let parent = path.parent().ok_or_else(|| {
io::Error::new(
io::ErrorKind::InvalidInput,
"bundled product runtime path must have a parent",
)
})?;
let name = path.file_name().ok_or_else(|| {
io::Error::new(
io::ErrorKind::InvalidInput,
"bundled product runtime path must have a final component",
)
})?;
Ok(parent.canonicalize()?.join(name))
}
Err(error) => Err(error),
}
}
pub(crate) fn imported_legacy_distros(home: &AosHome) -> io::Result<Vec<LegacyDistro>> {
let receipt = read_receipt(&home.migration_receipt())?;View on GitHub (pinned to f6f22024fb)