{"record":{"id":"075db546af072edf","repo":"jesseduffield/lazygit","slug":"command-output-contains-newlines-s","errorCode":null,"errorMessage":"command output contains newlines: %s","messagePattern":"command output contains newlines: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/commands/git_commands/custom.go","lineNumber":36,"sourceCode":"}\n\n// Only to be used for the sake of running custom commands specified by the user.\n// If you want to run a new command, try finding a place for it in one of the neighbouring\n// files, or creating a new BlahCommands struct to hold it.\nfunc (self *CustomCommands) RunWithOutput(cmdStr string) (string, error) {\n\treturn self.cmd.New(str.ToArgv(cmdStr)).RunWithOutput()\n}\n\n// A function that can be used as a \"runCommand\" entry in the template.FuncMap of templates.\nfunc (self *CustomCommands) TemplateFunctionRunCommand(cmdStr string) (string, error) {\n\toutput, err := self.RunWithOutput(cmdStr)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\toutput = strings.TrimRight(output, \"\\r\\n\")\n\n\tif strings.Contains(output, \"\\r\\n\") {\n\t\treturn \"\", fmt.Errorf(\"command output contains newlines: %s\", output)\n\t}\n\n\treturn output, nil\n}\n","sourceCodeStart":18,"sourceCodeEnd":41,"githubUrl":"https://github.com/jesseduffield/lazygit/blob/c477a2959b229fbf3284be0d4d2904ab61ec3c94/pkg/commands/git_commands/custom.go#L18-L41","documentation":"TemplateFunctionRunCommand executes a shell command from a custom-command template ({{runCommand ...}}) and requires single-line output: trailing newlines are trimmed, then any remaining '\\r\\n' makes it fail, because the result is interpolated back into a git command line where embedded newlines would break or inject lines.","triggerScenarios":"A custom command using runCommand whose command prints multiple lines (e.g. 'git branch --list', 'ls', any table output) — after trimming the final newline, interior CRLF pairs still remain and trigger the error.","commonSituations":"Piping a multi-line git query into a template placeholder; forgetting that the helper is designed for single-value lookups (version strings, hashes, names), not lists.","solutions":["Reduce the command to one line of output: add '| head -n1', 'awk NR==1', or make the query exact ('git rev-parse --short HEAD').","Strip CR if the tool emits CRLF: pipe through 'tr -d \"\\r\"' — the guard specifically looks for '\\r\\n' pairs.","For list-like data, run the command in the custom command itself, not via runCommand."],"exampleFix":"# before\ncommand: 'echo {{runCommand \"git branch --list main\"}}'\n# after\ncommand: 'echo {{runCommand \"git branch --list main | head -n1 | tr -d \"\\r\"\"}}'","handlingStrategy":"validation","validationCode":"// In your own runCommand-style helpers, enforce single-line output yourself:\nout, err := runWithOutput(cmd)\nif err != nil {\n    return \"\", err\n}\nout = strings.TrimRight(out, \"\\r\\n\")\nif strings.ContainsAny(out, \"\\r\\n\") {\n    return \"\", fmt.Errorf(\"expected single-line output from %q\", cmd)\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use runCommand only for single-value lookups (rev-parse, config get, head -n1).","Pipe multi-line sources through 'head -n1' / 'awk NR==1' and 'tr -d \"\\r\"' at the call site.","Never interpolate raw command output into shell strings without newline/quote sanitization."],"tags":["custom-commands","templates","shell","validation"],"backgroundTag":null,"analyzedSha":"c477a2959b229fbf3284be0d4d2904ab61ec3c94","analyzedAt":"2026-08-15T08:34:32.451Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}