nikivdev/code · error · anyhow::Error

failed to run ai-task.sh: {e}

Error message

failed to run ai-task.sh: {e}

What it means

Raised when `call_ai_explain` cannot spawn ai-task.sh at all — the `Err(e)` arm of the process launch. Unlike the non-zero-exit case, here the script never ran: the error wraps the OS-level spawn failure.

Source

Thrown at src/explain_commits.rs:249

            "5",
        ])
        .output();

    match output {
        Ok(out) if out.status.success() => {
            let text = String::from_utf8_lossy(&out.stdout).trim().to_string();
            if text.is_empty() {
                Ok("(AI returned empty response)".to_string())
            } else {
                Ok(text)
            }
        }
        Ok(out) => {
            let stderr = String::from_utf8_lossy(&out.stderr);
            bail!("ai-task.sh failed: {}", stderr.trim());
        }
        Err(e) => {
            bail!("failed to run ai-task.sh: {e}");
        }
    }
}

// -- Markdown output --

fn slugify(s: &str) -> String {
    s.chars()
        .map(|c| {
            if c.is_alphanumeric() || c == '-' {
                c.to_ascii_lowercase()
            } else if c == ' ' || c == '_' || c == '/' {
                '-'
            } else {
                '\0'
            }
        })
        .filter(|c| *c != '\0')

View on GitHub (pinned to a747e741ae)

Solutions

  1. Ensure ai-task.sh exists at the expected location (repo scripts directory) and run any repo setup/bootstrap step
  2. Make it executable: chmod +x ai-task.sh
  3. Verify it is reachable via PATH from the shell running f (echo $PATH; which ai-task.sh)
  4. Check that a POSIX shell (/bin/sh or bash) is installed — required on minimal containers/Windows WSL
  5. Confirm your version of the repo still ships ai-task.sh (it may have moved in an update)

Example fix

// before
f explain-last --ai   // failed to run ai-task.sh: No such file or directory
// after
chmod +x scripts/ai-task.sh && export PATH="$PWD/scripts:$PATH"
f explain-last --ai
Defensive patterns

Strategy: validation

Validate before calling

// ensure the script is present and executable before invoking
let p = std::path::Path::new("scripts/ai-task.sh");
if !p.exists() { bail!("ai-task.sh not found — run repo setup/bootstrap"); }
#[cfg(unix)]
{
    use std::os::unix::fs::PermissionsExt;
    if p.metadata()?.permissions().mode() & 0o111 == 0 {
        bail!("ai-task.sh is not executable — chmod +x it");
    }
}

Try / catch

match result {
    Err(e) if e.to_string().starts_with("failed to run ai-task.sh") => {
        eprintln!("Cannot launch ai-task.sh ({e}); check path/permissions");
    }
    other => other?,
}

Prevention

When it happens

Trigger: Command::new("ai-task.sh").output() returns Err at src/explain_commits.rs:249 — typically the file does not exist, is not executable, or the shell interpreter is missing on PATH.

Common situations: Fresh clone without the scripts/ setup step executed; file lost execute bit after copying on a filesystem without permissions; PATH differs in CI or non-interactive shells; script moved/renamed in a newer version.

Related errors


AI-assisted analysis of nikivdev/code@a747e741ae (2026-09-01). Data as JSON: /api/errors/f408f40dd5e1b93d. Report an issue: GitHub.