alibaba/open-code-review · error
%s failed: %w
Error message
%s failed: %w
What it means
gitFailure formats a failure from a git subprocess. When git wrote nothing to stderr, there is no diagnostic to show, so the error is simply '<op> failed: <wrapped err>'. It is the generic wrapper for runGitSplit failures across diff operations (git diff, merge-base, etc.).
Source
Thrown at internal/diff/git.go:709
// gitDiagLimit bounds how much of git's stderr is quoted back in an error.
// Git's own diagnosis is a line or two, so the ceiling is a backstop for the
// pathological case — a flood of warnings ahead of the fatal — rather than the
// common one.
const gitDiagLimit = 2000
// gitFailure builds an error that carries git's own message.
//
// Every diff-producing caller used to drop git's output on the floor, so a
// failure surfaced as a bare "git show failed: exit status 129" — true, and
// useless. Diagnosing one then meant asking the reporter to re-run the command
// by hand to see what git actually said (#972). The exit status alone cannot
// distinguish an unsupported option from a bad revision or a permission error.
//
// Callers pass stderr, never runGit's combined output; see runGitSplit for why.
func gitFailure(op, stderr string, err error) error {
diag := strings.TrimSpace(stderr)
if diag == "" {
return fmt.Errorf("%s failed: %w", op, err)
}
if len(diag) > gitDiagLimit {
// Keep the tail: die() exits the process, so the fatal git ends on is
// the last thing it writes, behind any warnings that preceded it.
diag = diag[len(diag)-gitDiagLimit:]
// Cutting by bytes can land mid-rune. Git speaks the user's locale,
// so this is not hypothetical — #972 came from a Japanese-language
// Windows install. Drop the partial leading rune rather than emit
// invalid UTF-8.
for len(diag) > 0 && !utf8.RuneStart(diag[0]) {
diag = diag[1:]
}
diag = "..." + diag
}
return fmt.Errorf("%s failed: %w: %s", op, err, diag)
}
View on GitHub (pinned to 5cf97d0d15)
Solutions
- Check git is installed and on PATH (git --version) since exec failures produce empty stderr
- Inspect the wrapped Go error (%w) for exit status or exec details
- Re-run the same git command manually in the repo to reproduce and see output
- Unset interfering GIT_* environment variables and retry
Defensive patterns
Strategy: try-catch
Validate before calling
if _, err := exec.LookPath("git"); err != nil { return fmt.Errorf("git not on PATH: %w", err) } Try / catch
d, err := differ.GetDiff(ctx, p)
if err != nil {
var execErr *exec.Error
if errors.As(err, &execErr) { return fmt.Errorf("git unavailable: %w", execErr) } // empty-stderr case
return err
} Prevention
- Verify the git binary exists in the deployment image before running diffs
- Avoid stripping environment (GIT_* variables, PATH) before subprocess calls
- Log the wrapped error chain; empty stderr means the cause is in the Go-wrapped err
When it happens
Trigger: Any runGitSplit call inside GetDiff (or an anonymous helper) returning an error while stderr is empty — e.g. git killed by a signal, exec failure before git started, or git failing without writing diagnostics.
Common situations: git binary missing or not on PATH (exec error, no stderr from git); git terminated by OOM/signal; extremely old git version failing oddly; environment issues (broken locale, GIT_DIR misconfig) that abort silently.
Understand the failure class
Background: "git command failed": what it means when a tool shells out to git and git exits non-zero — this error's family across 21 libraries.
Related errors
- %s failed: %w: %s
- git ls-files (tracked): %w
- git ls-files (untracked): %w
- git show %s:%s: %w
- preview failed: %w
AI-assisted analysis of alibaba/open-code-review@5cf97d0d15 (2026-09-02).
Data as JSON: /api/errors/8d84ea9c11604979.
Report an issue: GitHub.