{"record":{"id":"3b96306808fe7dfd","repo":"unicity-aos/aos-ce","slug":"bundled-executable-must-have-a-parent-directory","errorCode":null,"errorMessage":"bundled executable must have a parent directory","messagePattern":"bundled executable must have a parent directory","errorType":"exception","errorClass":"std::io::Error","httpStatus":null,"severity":"error","filePath":"crates/unicity-aos-bootstrap/src/lib.rs","lineNumber":359,"sourceCode":"    /// # Errors\n    /// Returns an error when the release runtime bin or inherited host PATH\n    /// cannot be represented safely as a child PATH.\n    pub fn runtime_command_with_args<I, S>(&self, args: I) -> io::Result<Command>\n    where\n        I: IntoIterator<Item = S>,\n        S: AsRef<OsStr>,\n    {\n        let runtime_binary = self.runtime_binary();\n        self.runtime_executable_command(&runtime_binary, args)\n    }\n\n    fn runtime_executable_command<I, S>(&self, executable: &Path, args: I) -> io::Result<Command>\n    where\n        I: IntoIterator<Item = S>,\n        S: AsRef<OsStr>,\n    {\n        let executable_parent = executable.parent().ok_or_else(|| {\n            io::Error::new(\n                io::ErrorKind::InvalidInput,\n                \"bundled executable must have a parent directory\",\n            )\n        })?;\n        // An explicit absolute package override points at a complete runtime\n        // bundle, so keep its sibling tools ahead of the host PATH as well.\n        let path_prefix = match std::env::var_os(\"UNICITY_AOS_RUNTIME_BIN\").map(PathBuf::from) {\n            Some(path) if path.is_absolute() => path\n                .parent()\n                .map(Path::to_path_buf)\n                .unwrap_or_else(|| executable_parent.to_path_buf()),\n            _ => self.release_runtime_bin_dir(),\n        };\n        let mut command = Command::new(executable);\n        command\n            .env(\"ASTRID_HOME\", self.runtime_home())\n            .env(\"ASTRID_WORKSPACE_STATE_DIR\", AOS_WORKSPACE_STATE_DIR)\n            .env(\"ASTRID_ENFORCED_DISTRO\", self.unicity_ce_manifest_path())","sourceCodeStart":341,"sourceCodeEnd":377,"githubUrl":"https://github.com/unicity-aos/aos-ce/blob/f6f22024fb1e8d122f28a1b4a9f75aee448ae839/crates/unicity-aos-bootstrap/src/lib.rs#L341-L377","documentation":"runtime_executable_command calls Path::parent() on the bundled executable path and, since parent() returns None only for paths with no parent component (e.g. a bare relative name resolved oddly or a root-less path), maps that to InvalidInput \"bundled executable must have a parent directory\". The parent is required to build the child process PATH that puts bundled sibling tools first.","triggerScenarios":"Calling runtime_executable_command (via runtime_command_with_args or foreground_daemon_command) with an executable Path whose parent() is None — practically only paths like \"/\" or pathological inputs that yield no parent component.","commonSituations":"A misconfigured override pointing the executable at a filesystem root or empty/degenerate path; constructing the path programmatically and accidentally passing \"\" or \"/\" instead of the binary file path.","solutions":["Pass the full absolute path to the executable file (e.g. /opt/runtime/bin/unicityd), never a directory root or empty path.","Resolve the executable with canonicalize() before invoking so the path always has a parent.","Validate the override path points to an existing file before building the Command."],"exampleFix":"// before\nlet exe = Path::new(\"\");\nlet cmd = runtime.runtime_executable_command(exe, args)?;\n// after\nlet exe = PathBuf::from(\"/opt/unicity/bin/unicityd\");\ndebug_assert!(exe.is_file());\nlet cmd = runtime.runtime_executable_command(&exe, args)?;","handlingStrategy":"validation","validationCode":"fn require_parented_file(exe: &Path) -> Result<(), String> {\n    if exe.parent().is_none() {\n        return Err(format!(\"executable path {:?} has no parent; use a full file path\", exe));\n    }\n    if !exe.is_file() {\n        return Err(format!(\"{:?} is not an existing file\", exe));\n    }\n    Ok(())\n}","typeGuard":"fn is_full_executable_path(exe: &Path) -> bool {\n    exe.parent().is_some() && exe.is_file()\n}","tryCatchPattern":"match runtime.runtime_command_with_args(&exe, args) {\n    Err(e) if e.to_string().contains(\"must have a parent directory\") => {\n        eprintln!(\"override executable must be a full file path, got {:?}\", exe);\n    }\n    other => other?,\n}","preventionTips":["Always pass absolute file paths (…/bin/<binary>) for executable overrides, never roots or bare names.","Canonicalize configured executable paths at load time with std::fs::canonicalize.","Add a startup assertion that every configured executable path has a parent and is a file."],"tags":["path","validation","process-spawn","rust"],"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"}