{"record":{"id":"1f118a29b5b75c12","repo":"jesseduffield/lazygit","slug":"dynamic-stdout-of-failed-command","errorCode":null,"errorMessage":"<dynamic: stdout of failed command>","messagePattern":"<dynamic: stdout of failed command>","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/commands/oscommands/cmd_obj_runner.go","lineNumber":321,"sourceCode":"\n\tself.log.Infof(\"%s (%s)\", cmdObj.ToString(), time.Since(t))\n\n\tif err != nil {\n\t\tif cmdObj.suppressOutputUnlessError {\n\t\t\t_, _ = self.guiIO.newCmdWriterFn().Write(combinedOutput.Bytes())\n\t\t}\n\n\t\terrStr := stderr.String()\n\t\tif errStr != \"\" {\n\t\t\treturn errors.New(errStr)\n\t\t}\n\n\t\tif cmdObj.ShouldIgnoreEmptyError() {\n\t\t\treturn nil\n\t\t}\n\t\tstdoutStr := stdout.String()\n\t\tif stdoutStr != \"\" {\n\t\t\treturn errors.New(stdoutStr)\n\t\t}\n\t\treturn errors.New(\"Command exited with non-zero exit code, but no output\")\n\t}\n\n\treturn nil\n}\n\ntype CredentialType int\n\nconst (\n\tPassword CredentialType = iota\n\tUsername\n\tPassphrase\n\tPIN\n\tToken\n)\n\n// Whenever we're asked for a password we return a nil channel to tell the","sourceCodeStart":303,"sourceCodeEnd":339,"githubUrl":"https://github.com/jesseduffield/lazygit/blob/c477a2959b229fbf3284be0d4d2904ab61ec3c94/pkg/commands/oscommands/cmd_obj_runner.go#L303-L339","documentation":"Returned from the streaming runner in pkg/commands/oscommands/cmd_obj_runner.go:321. It is the fallback after stderr was empty and the command did not opt into ShouldIgnoreEmptyError: if stdout is non-empty on a failed command, that stdout becomes the error. Some tools report failures on stdout only, so lazygit surfaces whichever stream had content.","triggerScenarios":"A streamed CmdObj exits non-zero, wrote nothing to stderr, did not set ShouldIgnoreEmptyError, but wrote to stdout. Typical for tools that print their error report to stdout (some diff drivers, hooks, or custom pager/diff tooling configured in lazygit).","commonSituations":"Custom diff tools or diffRenderers misconfigured and failing with output on stdout; git hooks printing failure text to stdout; external merge tools exiting non-zero.","solutions":["Read the error text; it is the captured stdout of the failed command","Identify which command failed via the lazygit command log (it records cmdObj.ToString())","Fix or reconfigure the failing external tool (path, arguments, exit behavior)","If empty-output failures are expected noise for this command, construct the CmdObj with the option that ignores empty errors"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"err := cmd.Run()\nif err != nil {\n    msg := err.Error()\n    // stdout-only failures: some tools print errors on stdout\n    if strings.HasPrefix(msg, \"error:\") || strings.Contains(msg, \"fatal:\") {\n        return fmt.Errorf(\"external tool failed: %w\", err)\n    }\n    return err\n}","preventionTips":["Configure external tools (diff/merge) to report on stderr for clearer failures","Verify custom tool paths exist before lazygit invokes them","When empty-output failure is benign, build the CmdObj with ignore-empty-error"],"tags":["git","subprocess","stdout","streaming"],"backgroundTag":null,"analyzedSha":"c477a2959b229fbf3284be0d4d2904ab61ec3c94","analyzedAt":"2026-08-15T08:34:32.451Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}