unicity-aos/aos-ce · error · io::Error
bundled product runtime is not installed
Error message
bundled product runtime is not installed
What it means
validate_target checks that the bundled product runtime target exists via symlink_metadata and is a real directory (not a symlink). If the target path does not exist at all, the metadata lookup failure is mapped to this InvalidInput error. It means the migration destination runtime has never been installed.
Solutions
- Install the bundled product runtime at the target path first, then rerun migrate_runtime
- Verify the target path with fs::symlink_metadata(target).is_ok() before migrating
- Correct the configured install prefix if the runtime is installed at a different location
- Reinstall the product if the directory was deleted by a failed upgrade or cleanup
Example fix
// before
migrate_runtime(&target, ...)?; // target missing
// after
if target.symlink_metadata().is_err() {
install_product_runtime(&target)?;
}
migrate_runtime(&target, ...)?; Defensive patterns
Strategy: validation
Validate before calling
fn bundled_runtime_installed(target: &std::path::Path) -> bool {
std::fs::symlink_metadata(target)
.map(|m| m.is_dir())
.unwrap_or(false)
} Try / catch
match migrate_runtime(&target, ...) {
Ok(()) => {},
Err(e) if e.to_string().contains("bundled product runtime is not installed") =>
eprintln!("install the product runtime at {} first", target.display()),
Err(e) => return Err(e),
} Prevention
- Run product installation before migration in your deployment order
- Pre-flight check symlink_metadata on the target path
- Pin and verify the install prefix in configuration to avoid path typos
- Guard cleanup scripts so they cannot delete the installed runtime directory
When it happens
Trigger: Calling migrate_runtime with validate flow where the target directory path does not exist on disk (symlink_metadata returns NotFound for the target).
Common situations: Running migration before the product installation step completed; a typo'd install prefix; the runtime directory was removed by cleanup or a failed upgrade.
Understand the failure class
Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.
Related errors
- standalone runtime has no existing system lock; refusing an…
- failed to preserve imported activation state
- failed to validate ephemeral state exclusion
- failed to inspect imported distro locks
- imported principal home contains a non-UTF-8 name
AI-assisted analysis of unicity-aos/aos-ce@f6f22024fb (2026-09-13).
Data as JSON: /api/errors/1644f68d78c0931a.
Report an issue: GitHub.
Appendix: source
Thrown at crates/unicity-aos-bootstrap/src/migration.rs:617
}
fn checked_root(path: &Path, description: &str) -> io::Result<PathBuf> {
if !path.is_absolute() {
return invalid(&format!("{description} must be an absolute path"));
}
let metadata = fs::symlink_metadata(path)?;
if metadata.file_type().is_symlink() || !metadata.is_dir() {
return invalid(&format!(
"{description} must be a real directory, not a symlink"
));
}
path.canonicalize()
}
fn validate_target(target: &Path, release_runtime_bin: &Path) -> io::Result<()> {
validate_release_runtime_bin(release_runtime_bin)?;
let target_metadata = fs::symlink_metadata(target).map_err(|_| {
io::Error::new(
io::ErrorKind::InvalidInput,
"bundled product runtime is not installed",
)
})?;
if target_metadata.file_type().is_symlink() || !target_metadata.is_dir() {
return invalid("bundled product runtime must be a real directory");
}
let bin = target.join("bin");
match fs::symlink_metadata(&bin) {
Ok(bin_metadata) => {
if bin_metadata.file_type().is_symlink() || !bin_metadata.is_dir() {
return invalid("bundled product runtime bin must be a real directory");
}
if fs::read_dir(&bin)?.next().transpose()?.is_some() {
return invalid(
"product runtime home contains data; migration refuses to merge state",
);
}View on GitHub (pinned to f6f22024fb)