nikivdev/code · error
failed to exec fish: {}
Error message
failed to exec fish: {} What it means
reload_fish_shell replaces the current process with `fish -l` via Command::exec on Unix. exec only returns if it failed, so any value returned means fish could not be started, and the code bails with the OS error interpolated. On non-Unix it spawns fish instead and never errors.
Source
Thrown at src/latest.rs:70
let result = deploy::run(DeployCommand { action: None });
std::env::set_current_dir(prev).context("failed to restore previous directory")?;
result
}
fn reload_fish_shell() -> Result<()> {
if std::env::var("FISH_VERSION").is_err() {
return Ok(());
}
if !atty::is(atty::Stream::Stdout) {
return Ok(());
}
println!("Reloading fish shell...");
#[cfg(unix)]
{
use std::os::unix::process::CommandExt;
let err = Command::new("fish").arg("-l").exec();
bail!("failed to exec fish: {}", err);
}
#[cfg(not(unix))]
{
let _ = Command::new("fish").arg("-l").status();
Ok(())
}
}
View on GitHub (pinned to a747e741ae)
Solutions
- Install fish (e.g. brew install fish or apt install fish) or add its directory to PATH
- Verify fish is runnable: `which fish` / `fish -l` in the same environment
- If you don't want a fish reload, run the command in an environment where the exec step is skipped (non-Unix path or alternate command)
Example fix
// before
let err = Command::new("fish").arg("-l").exec();
bail!("failed to exec fish: {}", err);
// after (check availability first)
if which::which("fish").is_err() {
bail!("fish not found on PATH; install fish or skip reload");
}
let err = Command::new("fish").arg("-l").exec();
bail!("failed to exec fish: {}", err); Defensive patterns
Strategy: validation
Validate before calling
fn fish_available() -> bool {
std::process::Command::new("fish")
.arg("-c")
.arg("true")
.output()
.map(|o| o.status.success())
.unwrap_or(false)
}
if !fish_available() { eprintln!("fish not installed/on PATH; reload skipped"); } Type guard
fn is_unix() -> bool { cfg!(unix) } Try / catch
match reload_fish_shell() {
Err(e) if e.to_string().starts_with("failed to exec fish") => {
eprintln!("fish exec failed — is fish installed and on PATH?");
}
other => other?,
} Prevention
- Install fish on all dev machines; keep it on PATH for non-interactive shells
- Verify `command -v fish` in shell profiles/CI before relying on reload
- Fall back to `exec $SHELL` if fish is unavailable
When it happens
Trigger: Calling run on a Unix system when the exec of `fish -l` fails: fish is not installed or not on PATH, the binary lacks execute permission, or the exec syscall fails for another OS-level reason.
Common situations: Machine uses bash/zsh and fish was never installed; fish installed outside PATH (e.g. /opt/homebrew/bin not in PATH in a non-interactive context); minimal container images without fish.
Related errors
- handled before project context load
- ai not found in PATH
- failed to launch Cursor
- binary '{}' not found
- bun or npm is required to install docs hub dependencies
AI-assisted analysis of nikivdev/code@a747e741ae (2026-09-01).
Data as JSON: /api/errors/f3738257a502f5c8.
Report an issue: GitHub.