{"record":{"id":"8c8d5e03a231d7b0","repo":"alibaba/open-code-review","slug":"s-failed-w-s","errorCode":null,"errorMessage":"%s failed: %w: %s","messagePattern":"(.+?) failed: %w: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/diff/git.go","lineNumber":724,"sourceCode":"func gitFailure(op, stderr string, err error) error {\n\tdiag := strings.TrimSpace(stderr)\n\tif diag == \"\" {\n\t\treturn fmt.Errorf(\"%s failed: %w\", op, err)\n\t}\n\tif len(diag) > gitDiagLimit {\n\t\t// Keep the tail: die() exits the process, so the fatal git ends on is\n\t\t// the last thing it writes, behind any warnings that preceded it.\n\t\tdiag = diag[len(diag)-gitDiagLimit:]\n\t\t// Cutting by bytes can land mid-rune. Git speaks the user's locale,\n\t\t// so this is not hypothetical — #972 came from a Japanese-language\n\t\t// Windows install. Drop the partial leading rune rather than emit\n\t\t// invalid UTF-8.\n\t\tfor len(diag) > 0 && !utf8.RuneStart(diag[0]) {\n\t\t\tdiag = diag[1:]\n\t\t}\n\t\tdiag = \"...\" + diag\n\t}\n\treturn fmt.Errorf(\"%s failed: %w: %s\", op, err, diag)\n}\n","sourceCodeStart":706,"sourceCodeEnd":726,"githubUrl":"https://github.com/alibaba/open-code-review/blob/5cf97d0d15cbd41b602513c4be3bfec3cee5bf7f/internal/diff/git.go#L706-L726","documentation":"gitFailure's richer variant: when git did write diagnostics to stderr, the error is '<op> failed: <wrapped err>: <diagnostic tail>'. Diagnostics longer than gitDiagLimit are truncated to the tail (git's die() message is last), and invalid UTF-8 at the cut point is trimmed. This is the most informative git diff failure path.","triggerScenarios":"Any runGitSplit call in GetDiff failing with non-empty stderr — bad revision names, permission errors, unsupported options, corrupt repo, external diff tool failures.","commonSituations":"Typo'd commit/ref in from/to; diffing in a directory that is not a git repo; core.externalDiff tool broken or missing; file permission errors during diff; locale-dependent messages (stderr is passed raw to preserve them).","solutions":["Read the appended git diagnostic in the error — it states the concrete cause (unknown revision, not a repo, etc.)","Fix the specific git issue the diagnostic names (correct the ref, run inside a repo, repair the external diff tool)","Re-run the equivalent git command manually to confirm the fix","Verify repo integrity (git fsck) if diagnostics suggest corruption"],"exampleFix":"// before\np.from = \"mainn\" // typo -> 'git diff failed: ...: unknown revision mainn'\n// after\np.from = \"main\"","handlingStrategy":"try-catch","validationCode":"// verify refs and repo before diffing\nfor _, ref := range []string{from, to} {\n    if err := exec.Command(\"git\", \"-C\", dir, \"rev-parse\", \"--verify\", ref).Run(); err != nil {\n        return fmt.Errorf(\"bad ref %s\", ref)\n    }\n}","typeGuard":null,"tryCatchPattern":"d, err := differ.GetDiff(ctx, p)\nif err != nil {\n    if strings.Contains(err.Error(), \"not a git repository\") { return errRepoMissing }\n    if strings.Contains(err.Error(), \"unknown revision\") { return errBadRef }\n    return err // diagnostic tail already included\n}","preventionTips":["Read the ': <stderr>' suffix — it contains git's own explanation of the failure","Validate refs with git rev-parse before requesting diffs","Run diffs only inside initialized repositories; avoid broken core.attributesEvaluator/external diff configs"],"tags":["git","subprocess","stderr","diagnostics"],"backgroundTag":"git-command-failed","analyzedSha":"5cf97d0d15cbd41b602513c4be3bfec3cee5bf7f","analyzedAt":"2026-09-02T02:08:09.116Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}