{"record":{"id":"d54f0b5b89045d85","repo":"unicity-aos/aos-ce","slug":"aos-capsule-directory-is-unavailable-at-error","errorCode":null,"errorMessage":"AOS capsule directory is unavailable at {}: {error}","messagePattern":"AOS capsule directory is unavailable at (.+?): (.+?)","errorType":"validation","errorClass":"io::Error","httpStatus":null,"severity":"error","filePath":"crates/unicity-aos-bootstrap/src/lib.rs","lineNumber":716,"sourceCode":"            return Err(io::Error::new(\n                io::ErrorKind::InvalidData,\n                format!(\"embedded capsule source does not match package {package}\"),\n            ));\n        }\n        if assets.contains(&asset) {\n            return Err(io::Error::new(\n                io::ErrorKind::InvalidData,\n                format!(\"embedded distro selects duplicate capsule asset {asset}\"),\n            ));\n        }\n        assets.push(asset);\n    }\n    Ok(assets)\n}\n\nfn validate_capsule_dir(path: &Path, expected: &[String]) -> io::Result<PathBuf> {\n    let metadata = fs::symlink_metadata(path).map_err(|error| {\n        io::Error::new(\n            error.kind(),\n            format!(\n                \"AOS capsule directory is unavailable at {}: {error}\",\n                path.display()\n            ),\n        )\n    })?;\n    if metadata.file_type().is_symlink() || !metadata.is_dir() {\n        return Err(io::Error::new(\n            io::ErrorKind::InvalidInput,\n            format!(\n                \"AOS capsule directory must be a real directory: {}\",\n                path.display()\n            ),\n        ));\n    }\n    let canonical = path.canonicalize()?;\n    let mut actual = Vec::new();","sourceCodeStart":698,"sourceCodeEnd":734,"githubUrl":"https://github.com/unicity-aos/aos-ce/blob/f6f22024fb1e8d122f28a1b4a9f75aee448ae839/crates/unicity-aos-bootstrap/src/lib.rs#L698-L734","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Create the capsule directory (install_capsule_fixtures does this) before validating it","Check and correct the configured AOS home / capsule directory path","Verify the process has read permission on the directory's parent chain","Inspect the wrapped io::ErrorKind (NotFound, PermissionDenied) to identify the exact cause"],"exampleFix":"// before\nlet dir = validate_capsule_dir(&maybe_missing_path, &expected)?;\n// after\nfs::create_dir_all(&capsule_dir)?;\nlet dir = validate_capsule_dir(&capsule_dir, &expected)?;","handlingStrategy":"try-catch","validationCode":"fn capsule_dir_exists(path: &std::path::Path) -> bool {\n    std::fs::symlink_metadata(path).is_ok()\n}","typeGuard":null,"tryCatchPattern":"match bootstrap::capsule_dir_with(&home) {\n    Err(e) if e.kind() == std::io::ErrorKind::NotFound => {\n        std::fs::create_dir_all(&capsules_path)?;\n        bootstrap::capsule_dir_with(&home)\n    }\n    Err(e) => Err(e),\n    Ok(dir) => Ok(dir),\n}","preventionTips":["Always create the capsule directory (or run install_capsule_fixtures) before validating","Check the configured AOS home path early at startup","Match on io::ErrorKind to distinguish NotFound from PermissionDenied"],"tags":["rust","filesystem","directory-not-found","capsules"],"backgroundTag":"directory-not-found","analyzedSha":"f6f22024fb1e8d122f28a1b4a9f75aee448ae839","analyzedAt":"2026-09-13T03:04:44.565Z","contentChangedAt":"2026-09-13T03:04:44.565Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}