unicity-aos/aos-ce · error · io::Error

completed product runtime is not installed

Error message

completed product runtime is not installed

What it means

validate_completed_target mirrors validate_target for the completed-migration path: it requires the target to exist (symlink_metadata) and be a real directory. A missing target maps to this InvalidInput error with the "completed product runtime" wording. It indicates the post-migration runtime installation is absent.

Solutions

  1. Ensure the migration step that installs the completed runtime actually ran and wrote the target directory
  2. Re-run the migration to completion before invoking the completed-state validation
  3. Verify the receipt's recorded target matches the actual installed path

Example fix

// before
validate_completed_target(&target, &bin, &receipt)?; // target absent

// after
assert!(target.symlink_metadata().is_ok(), "runtime not installed");
validate_completed_target(&target, &bin, &receipt)?;
Defensive patterns

Strategy: validation

Validate before calling

fn completed_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("completed product runtime is not installed") =>
        eprintln!("migration incomplete; re-run to install the completed runtime"),
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Calling migrate_runtime's completed-path validation when the final target directory has not been created or was deleted before validation runs.

Common situations: A migration run interrupted before the target was installed; running the completed-state validation against a machine where only staging exists; a wrong receipt/target pairing.

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


AI-assisted analysis of unicity-aos/aos-ce@f6f22024fb (2026-09-13). Data as JSON: /api/errors/4e8de267a9fbd24a. Report an issue: GitHub.

Appendix: source

Thrown at crates/unicity-aos-bootstrap/src/migration.rs:658

    for entry in fs::read_dir(target)? {
        let entry = entry?;
        let path = entry.path();
        let metadata = fs::symlink_metadata(&path)?;
        if path != bin || metadata.file_type().is_symlink() || !metadata.is_dir() {
            return invalid("product runtime home contains data; migration refuses to merge state");
        }
    }
    Ok(())
}

fn validate_completed_target(
    target: &Path,
    release_runtime_bin: &Path,
    _receipt: &Receipt,
) -> io::Result<()> {
    validate_release_runtime_bin(release_runtime_bin)?;
    let target_metadata = fs::symlink_metadata(target).map_err(|_| {
        io::Error::new(
            io::ErrorKind::InvalidInput,
            "completed product runtime is not installed",
        )
    })?;
    if target_metadata.file_type().is_symlink() || !target_metadata.is_dir() {
        return invalid("completed 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("completed product runtime bin must be a real directory");
            }
            for entry in fs::read_dir(&bin)? {
                let entry = entry?;
                let name = entry.file_name();
                if RUNTIME_EXECUTABLE_NAMES
                    .iter()

View on GitHub (pinned to f6f22024fb)