helix-editor/helix · error · anyhow::Error

Git command failed. Stdout: {} Stderr: {}

Error message

Git command failed.
Stdout: {}
Stderr: {}

What it means

Raised by helix-loader's grammar fetch helper when a 'git' invocation inside the grammar sources directory exits non-zero; stdout and stderr of git are embedded verbatim. This is the generic wrapper for every git failure during 'hx --grammar fetch' (clone, fetch, checkout of pinned revisions).

Source

Thrown at helix-loader/src/grammar.rs:489

// A wrapper around 'git' commands which returns stdout in success and a
// helpful error message showing the command, stdout, and stderr in error.
fn git<I, S>(repository_dir: &Path, args: I) -> Result<String>
where
    I: IntoIterator<Item = S>,
    S: AsRef<std::ffi::OsStr>,
{
    let output = Command::new("git")
        .args(args)
        .current_dir(repository_dir)
        .output()?;

    if output.status.success() {
        Ok(String::from_utf8_lossy(&output.stdout)
            .trim_end()
            .to_owned())
    } else {
        // TODO: figure out how to display the git command using `args`
        Err(anyhow!(
            "Git command failed.\nStdout: {}\nStderr: {}",
            String::from_utf8_lossy(&output.stdout),
            String::from_utf8_lossy(&output.stderr),
        ))
    }
}

enum BuildStatus {
    AlreadyBuilt,
    Built,
}

fn build_grammar(grammar: GrammarConfiguration, target: Option<&str>) -> Result<BuildStatus> {
    let grammar_dir = if let GrammarSource::Local { path } = &grammar.source {
        PathBuf::from(&path)
    } else {
        crate::runtime_dirs()
            .first()

View on GitHub (pinned to 079a789e8c)

Solutions

  1. Read the embedded Stderr first - it names the actual git failure (network, TLS, 'dubious ownership', missing ref)
  2. For dubious ownership: git config --global --add safe.directory <grammar sources dir shown in the error>
  3. For network issues: fix proxy/DNS or retry when online; run the same git command manually in the reported sources directory to reproduce
  4. If the pinned revision is gone: update Helix (revised pins) or override the grammar source in languages.toml to a branch/tag that exists

Example fix

# before: hx --grammar fetch fails with 'fatal: unable to access ...':
# after: configure proxy then retry
git config --global http.proxy http://proxy.example.com:8080
hx --grammar fetch
Defensive patterns

Strategy: retry

Validate before calling

// Pre-flight: is git available and is the host reachable?
fn fetch_preconditions_ok() -> bool {
    std::process::Command::new("git").arg("--version").output().is_ok_and(|o| o.status.success())
}

Try / catch

// Grammar fetch is a Result-returning function; retry transient network
// failures a couple of times, fail fast on permanent ones:
let mut attempt = 0;
loop {
    match helix_loader::grammar::fetch_grammars() {
        Ok(()) => break,
        Err(e) if attempt < 2 && e.to_string().contains("Connection") => { attempt += 1; continue; }
        Err(e) => { eprintln!("grammar fetch failed: {e}"); std::process::exit(1); }
    }
}

Prevention

When it happens

Trigger: Running 'hx --grammar fetch' (or first use triggering fetch) while offline, behind a misconfigured proxy, with an unreachable/censored git host, when a pinned revision no longer exists upstream, or when git itself errors (bad object database, unsafe repository ownership 'detected dubious ownership').

Common situations: Corporate proxy/MITM TLS rejecting github.com; a grammar repo force-pushed and the pinned commit vanished; git safe.directory refusing a cache dir written by another user; GitHub rate limiting or DNS failure. Note git's HTTP errors often appear only in the embedded stderr.

Related errors


AI-assisted analysis of helix-editor/helix@079a789e8c (2026-08-16). Data as JSON: /api/errors/d175cb689ad28807. Report an issue: GitHub.