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

  1. Check git is installed and on PATH (git --version) since exec failures produce empty stderr
  2. Inspect the wrapped Go error (%w) for exit status or exec details
  3. Re-run the same git command manually in the repo to reproduce and see output
  4. 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

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


AI-assisted analysis of alibaba/open-code-review@5cf97d0d15 (2026-09-02). Data as JSON: /api/errors/8d84ea9c11604979. Report an issue: GitHub.