{"record":{"id":"fa2a657a11757b37","repo":"charmbracelet/gum","slug":"failed-to-write-to-stdout-w","errorCode":null,"errorMessage":"failed to write to stdout: %w","messagePattern":"failed to write to stdout: %w","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"spin/command.go","lineNumber":56,"sourceCode":"\tdefer cancel()\n\n\ttm, err := tea.NewProgram(\n\t\tm,\n\t\ttea.WithOutput(os.Stderr),\n\t\ttea.WithContext(ctx),\n\t\ttea.WithInput(nil),\n\t).Run()\n\tif err != nil {\n\t\treturn fmt.Errorf(\"unable to run action: %w\", err)\n\t}\n\n\tm = tm.(model)\n\t// If the command succeeds, and we are printing output and we are in a TTY then push the STDOUT we got to the actual\n\t// STDOUT for piping or other things.\n\t//nolint:nestif\n\tif m.err != nil {\n\t\tif _, err := fmt.Fprintf(os.Stderr, \"%s\\n\", m.err.Error()); err != nil {\n\t\t\treturn fmt.Errorf(\"failed to write to stdout: %w\", err)\n\t\t}\n\t\treturn exit.ErrExit(1)\n\t} else if m.status == 0 {\n\t\tvar output string\n\t\tif o.ShowOutput || (o.ShowStdout && o.ShowStderr) {\n\t\t\toutput = m.output\n\t\t} else if o.ShowStdout {\n\t\t\toutput = m.stdout\n\t\t} else if o.ShowStderr {\n\t\t\toutput = m.stderr\n\t\t}\n\t\tif output != \"\" {\n\t\t\tif _, err := os.Stdout.WriteString(output); err != nil {\n\t\t\t\treturn fmt.Errorf(\"failed to write to stdout: %w\", err)\n\t\t\t}\n\t\t}\n\t} else if o.ShowError {\n\t\t// Otherwise if we are showing errors and the command did not exit with a 0 status code then push all of the command","sourceCodeStart":38,"sourceCodeEnd":74,"githubUrl":"https://github.com/charmbracelet/gum/blob/4d089f95507708a71f64dacfe7ca513219dd5267/spin/command.go#L38-L74","documentation":"When the action run by gum spin fails (m.err != nil), the error is printed to stderr; if even that Fprintf to stderr fails, Run returns this misleadingly-worded 'failed to write to stdout' wrapper. It signals the process cannot write to standard streams at all.","triggerScenarios":"m.err set by the spin action AND the subsequent fmt.Fprintf(os.Stderr, ...) returning an error — e.g. closed/broken stderr pipe (`cmd 2>&- | ...`), full disk, or a broken pipe on the receiving end.","commonSituations":"Shell pipelines that closed stderr; containers with no stderr attached; disk-full conditions while a long spin action failed.","solutions":["Fix the underlying action error (printed via m.err) first — that's the real failure.","Ensure stderr is open/attached when running gum spin (don't redirect it to a closed descriptor).","Check disk space and file descriptor limits.","Handle SIGPIPE/broken-pipe semantics in the surrounding pipeline."],"exampleFix":"// before (stderr closed)\ngum spin -- ./build.sh 2>&-\n// after\ngum spin -- ./build.sh 2>spin.log","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"if ! gum spin -- ./build.sh 2>spin.err; then cat spin.err >&2; fi  # keep stderr open and capture the real action error","preventionTips":["Never close or redirect stderr to a closed descriptor","Keep stderr attached in containers","Monitor disk space in long-running jobs","Read the wrapped action error first — it is the real cause"],"tags":["io","stdout","stderr","broken-pipe"],"backgroundTag":"stdout-write-failed","analyzedSha":"4d089f95507708a71f64dacfe7ca513219dd5267","analyzedAt":"2026-08-31T18:45:06.436Z","schemaVersion":2},"datasetVersion":"2026-08-31T22:30:34.772Z"}