Hmbown/CodeWhale · error · io::Error
not found on PATH
Error message
{} not found on PATH What it means
The dependencies::Gh-style tool wrapper's output() helper runs the external tool and captures stdout/stderr; if Self::command() cannot locate the tool binary on PATH it returns an io::Error (NotFound) formatted as '{type name} not found on PATH'. The type name in the message identifies which tool was missing.
Solutions
- Install the named tool (see type name in the message) and ensure it is on PATH
- Relaunch codewhale from a shell where `which <tool>` resolves
- Fix PATH in the launching environment (shell profile, systemd unit, IDE settings)
Example fix
// before Git::output(&["status"], repo_dir)? // Err: cratename::Git not found on PATH // after $ which git || apt install git $ codewhale # relaunched with git on PATH
Defensive patterns
Strategy: try-catch
Validate before calling
fn tool_on_path<T: Dependency>() -> bool { T::command().is_some() } Type guard
fn tool_available(cmd: &mut std::process::Command) -> bool { cmd.args(["--version"]).output().map(|o| o.status.success()).unwrap_or(false) } Try / catch
match Tool::output(&["arg"], cwd) {
Err(e) if e.kind() == std::io::ErrorKind::NotFound => eprintln!("{}: install it and add to PATH", e),
other => other?,
} Prevention
- Validate all external tool dependencies at startup (doctor command)
- Avoid relying on user-specific shims in service environments; use absolute tool paths
- Keep PATH consistent between interactive shells and launched processes
When it happens
Trigger: Calling the output() convenience (e.g. tool.output(&["arg"], cwd)) for a tracked dependency whose executable is absent from PATH in the current process environment.
Common situations: Tools installed per-user (nvm/rustup shims) while codewhale runs under a different user or service; minimal containers; IDE-spawned processes inheriting a stripped PATH.
Related errors
- dsh is not on PATH; install the official DeepSeek Harness…
- DSH plugin path not available
- NotFound
- A positive pull request number is required
- account_agent_model_unconfigured
AI-assisted analysis of Hmbown/CodeWhale@433685b202 (2026-09-15).
Data as JSON: /api/errors/e03bd5810a094919.
Report an issue: GitHub.
Appendix: source
Thrown at crates/tui/src/dependencies.rs:354
///
/// Callers should chain `.args(...)`, `.current_dir(...)`, and then
/// call `.output()`, `.status()`, or `.spawn()`.
fn command() -> Option<Command> {
let spec = Self::resolve()?;
let (program, fixed_args) = split_interpreter_spec(&spec);
let mut cmd = Command::new(&program);
crate::utils::suppress_console_window(&mut cmd);
for arg in &fixed_args {
cmd.arg(arg);
}
Some(cmd)
}
/// Convenience: run the tool with arguments in a working directory
/// and return the captured output.
fn output(args: &[&str], cwd: &std::path::Path) -> std::io::Result<std::process::Output> {
let mut cmd = Self::command().ok_or_else(|| {
std::io::Error::new(
std::io::ErrorKind::NotFound,
format!("{} not found on PATH", std::any::type_name::<Self>()),
)
})?;
cmd.args(args).current_dir(cwd).output()
}
/// Convenience: run the tool with arguments and return only the
/// exit status (discards stdout/stderr).
#[allow(dead_code)]
fn status(args: &[&str], cwd: &std::path::Path) -> std::io::Result<std::process::ExitStatus> {
let mut cmd = Self::command().ok_or_else(|| {
std::io::Error::new(
std::io::ErrorKind::NotFound,
format!("{} not found on PATH", std::any::type_name::<Self>()),
)
})?;
cmd.args(args).current_dir(cwd).status()View on GitHub (pinned to 433685b202)