{"record":{"id":"1212685e393ee3ca","repo":"kubernetes/kops","slug":"error-writing-to-stdout-v","errorCode":null,"errorMessage":"error writing to stdout: %v","messagePattern":"error writing to stdout: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"cmd/kops/get.go","lineNumber":85,"sourceCode":"\tcmd.AddCommand(NewCmdGetCluster(f, out, options))\n\tcmd.AddCommand(NewCmdGetInstanceGroups(f, out, options))\n\tcmd.AddCommand(NewCmdGetInstances(f, out, options))\n\tcmd.AddCommand(NewCmdGetKeypairs(f, out, options))\n\tcmd.AddCommand(NewCmdGetSecrets(f, out, options))\n\tcmd.AddCommand(NewCmdGetSSHPublicKeys(f, out, options))\n\n\treturn cmd\n}\n\nfunc RunGet(ctx context.Context, f commandutils.Factory, out io.Writer, options *GetOptions) error {\n\tklog.Warning(\"`kops get [CLUSTER]` is deprecated: use `kops get all [CLUSTER]`\")\n\treturn RunGetAll(ctx, f, out, &GetAllOptions{options})\n}\n\nfunc writeYAMLSep(out io.Writer) error {\n\t_, err := out.Write([]byte(\"\\n---\\n\\n\"))\n\tif err != nil {\n\t\treturn fmt.Errorf(\"error writing to stdout: %v\", err)\n\t}\n\treturn nil\n}\n\ntype marshalFunc func(obj runtime.Object) ([]byte, error)\n\nfunc marshalToWriter(obj runtime.Object, marshal marshalFunc, w io.Writer) error {\n\tb, err := marshal(obj)\n\tif err != nil {\n\t\treturn err\n\t}\n\t_, err = w.Write(b)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"error writing to stdout: %v\", err)\n\t}\n\treturn nil\n}\n","sourceCodeStart":67,"sourceCodeEnd":103,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/cmd/kops/get.go#L67-L103","documentation":"writeYAMLSep writes the \"\\n---\\n\\n\" document separator used when concatenating multiple resources into one YAML stream for `kops get -o yaml`. If the io.Writer (os.Stdout, or a redirected pipe/file) returns an error, it is wrapped as \"error writing to stdout\".","triggerScenarios":"`kops get <type> -o yaml` (fullOutputYAML path) when stdout is closed or the write fails — e.g. output piped to a command that exited early (SIGPIPE/EPIPE), disk-full redirect target, or closed descriptor.","commonSituations":"`kops get clusters -o yaml | head -1` causing head to exit and the pipe to break; redirecting to a file on a full filesystem; stdout connected to a dead process in a CI pipeline.","solutions":["Check why stdout failed: ensure the downstream pipe consumer stays alive (use `head -c` alternatives or temp files)","Verify redirect target has space: df -h on the output file's filesystem","Rerun writing to a file instead of a pipe: kops get -o yaml > out.yaml (if out.yaml is on a healthy fs)","Ignore if caused by expected SIGPIPE in shell pipelines (bash reports 141)"],"exampleFix":"// before (breaks)\nkops get ig -o yaml | head -1\n// after\nkops get ig -o yaml > ig.yaml && head -1 ig.yaml","handlingStrategy":"fallback","validationCode":"// check stdout is a healthy writable target before running\nif fi, err := os.Stdout.Stat(); err == nil && (fi.Mode()&os.ModeCharDevice) == 0 {\n    // piped: ensure downstream consumer will not exit early\n}","typeGuard":null,"tryCatchPattern":"out, err := exec.Command(\"kops\", \"get\", \"ig\", \"-o\", \"yaml\").Output()\nif err != nil {\n    if strings.Contains(err.Error(), \"error writing to stdout\") || exitCode(err) == 141 {\n        // broken pipe: write to a file instead and read it\n    }\n}","preventionTips":["Avoid piping kops output into commands that exit early (head, jq -e on bad input)","Redirect large outputs to files, then post-process","Monitor for shell exit code 141 (SIGPIPE)","Ensure redirect targets have free disk space"],"tags":["io","stdout","pipe"],"backgroundTag":"broken-pipe","analyzedSha":"4c8573c808a73d578c5eadc86d410646ea0b0d73","analyzedAt":"2026-09-05T04:13:19.212Z","contentChangedAt":"2026-09-05T04:13:19.212Z","schemaVersion":2},"datasetVersion":"2026-09-12T07:17:12.445Z"}