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

AOS capsule directory is unavailable at

Error message

AOS capsule directory is unavailable at {}: {error}

What it means

Thrown by validate_capsule_dir when fs::symlink_metadata cannot stat the AOS capsule directory path, typically because it does not exist or is inaccessible. The bootstrap library maps the OS error, preserving its kind, and annotates it with the path so the caller knows which directory is missing.

Solutions

  1. Create the capsule directory (install_capsule_fixtures does this) before validating it
  2. Check and correct the configured AOS home / capsule directory path
  3. Verify the process has read permission on the directory's parent chain
  4. Inspect the wrapped io::ErrorKind (NotFound, PermissionDenied) to identify the exact cause

Example fix

// before
let dir = validate_capsule_dir(&maybe_missing_path, &expected)?;
// after
fs::create_dir_all(&capsule_dir)?;
let dir = validate_capsule_dir(&capsule_dir, &expected)?;
Defensive patterns

Strategy: try-catch

Validate before calling

fn capsule_dir_exists(path: &std::path::Path) -> bool {
    std::fs::symlink_metadata(path).is_ok()
}

Try / catch

match bootstrap::capsule_dir_with(&home) {
    Err(e) if e.kind() == std::io::ErrorKind::NotFound => {
        std::fs::create_dir_all(&capsules_path)?;
        bootstrap::capsule_dir_with(&home)
    }
    Err(e) => Err(e),
    Ok(dir) => Ok(dir),
}

Prevention

When it happens

Trigger: Calling capsule_dir_with (directly or via prepare_unicity_ce_init / install_capsule_fixtures) with a path that has not been created yet, was deleted, or is not readable due to permissions.

Common situations: Running the bootstrap before the capsule directory was created; a prior run cleaned the directory; wrong AOS home path configured; running under a user lacking read access to the directory.

Related errors


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

Appendix: source

Thrown at crates/unicity-aos-bootstrap/src/lib.rs:716

            return Err(io::Error::new(
                io::ErrorKind::InvalidData,
                format!("embedded capsule source does not match package {package}"),
            ));
        }
        if assets.contains(&asset) {
            return Err(io::Error::new(
                io::ErrorKind::InvalidData,
                format!("embedded distro selects duplicate capsule asset {asset}"),
            ));
        }
        assets.push(asset);
    }
    Ok(assets)
}

fn validate_capsule_dir(path: &Path, expected: &[String]) -> io::Result<PathBuf> {
    let metadata = fs::symlink_metadata(path).map_err(|error| {
        io::Error::new(
            error.kind(),
            format!(
                "AOS capsule directory is unavailable at {}: {error}",
                path.display()
            ),
        )
    })?;
    if metadata.file_type().is_symlink() || !metadata.is_dir() {
        return Err(io::Error::new(
            io::ErrorKind::InvalidInput,
            format!(
                "AOS capsule directory must be a real directory: {}",
                path.display()
            ),
        ));
    }
    let canonical = path.canonicalize()?;
    let mut actual = Vec::new();

View on GitHub (pinned to f6f22024fb)