{"record":{"id":"ed0ae6095691c4a0","repo":"unicity-aos/aos-ce","slug":"aos-capsule-directory-contains-a-non-regular-entry","errorCode":null,"errorMessage":"AOS capsule directory contains a non-regular entry: {}","messagePattern":"AOS capsule directory contains a non-regular entry: (.+?)","errorType":"validation","errorClass":"io::Error","httpStatus":null,"severity":"error","filePath":"crates/unicity-aos-bootstrap/src/lib.rs","lineNumber":739,"sourceCode":"            ),\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();\n    for entry in fs::read_dir(&canonical)? {\n        let entry = entry?;\n        let metadata = fs::symlink_metadata(entry.path())?;\n        if metadata.file_type().is_symlink() || !metadata.is_file() {\n            return Err(io::Error::new(\n                io::ErrorKind::InvalidInput,\n                format!(\n                    \"AOS capsule directory contains a non-regular entry: {}\",\n                    entry.path().display()\n                ),\n            ));\n        }\n        let name = entry.file_name().into_string().map_err(|_| {\n            io::Error::new(\n                io::ErrorKind::InvalidInput,\n                \"AOS capsule directory contains a non-UTF-8 entry\",\n            )\n        })?;\n        actual.push(name);\n    }\n    actual.sort();\n    let mut expected = expected.to_vec();\n    expected.sort();","sourceCodeStart":721,"sourceCodeEnd":757,"githubUrl":"https://github.com/unicity-aos/aos-ce/blob/f6f22024fb1e8d122f28a1b4a9f75aee448ae839/crates/unicity-aos-bootstrap/src/lib.rs#L721-L757","documentation":"Thrown by validate_capsule_dir when an entry inside the capsule directory is a symlink or not a regular file. The library requires every entry to be a plain file so the capsule set is tamper-evident and portable; nested directories, links, devices, or sockets are rejected.","triggerScenarios":"Placing subdirectories, symlinks, sockets, or device nodes inside the capsule directory before calling capsule_dir_with; leaving editor/VCS artifacts (e.g. symlinked files) inside the directory.","commonSituations":"Users pre-populating the directory with unpacked capsule trees; symlinking capsule files into the directory from elsewhere; leftover temporary files from interrupted runs.","solutions":["Remove or replace any non-regular entry inside the capsule directory with a regular file copy","Ensure only the expected .capsule files (plain files) are present","Clean and regenerate the directory via install_capsule_fixtures"],"exampleFix":"// before\nln -s /opt/capsules/auth.capsule ~/.aos/capsules/auth.capsule\n// after\ncp /opt/capsules/auth.capsule ~/.aos/capsules/auth.capsule","handlingStrategy":"validation","validationCode":"fn dir_has_only_regular_files(path: &std::path::Path) -> bool {\n    std::fs::read_dir(path).map(|rd| rd.filter_map(|e| e.ok()).all(|e| {\n        std::fs::symlink_metadata(e.path())\n            .map(|md| !md.file_type().is_symlink() && md.is_file())\n            .unwrap_or(false)\n    })).unwrap_or(false)\n}","typeGuard":null,"tryCatchPattern":"match bootstrap::capsule_dir_with(&home) {\n    Err(e) if e.to_string().contains(\"non-regular entry\") => {\n        eprintln!(\"Remove or flatten non-file entries inside the capsule directory: {e}\");\n    }\n    Err(e) => return Err(e),\n    Ok(dir) => dir,\n}","preventionTips":["Only place plain .capsule files in the capsule directory; no subdirectories or symlinks","Regenerate the directory with install_capsule_fixtures instead of hand-populating it","Exclude editor and VCS artifacts from the directory"],"tags":["rust","filesystem","symlink","capsules"],"backgroundTag":"invalid-argument-value","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"}