{"record":{"id":"8ff7803cb6fbf080","repo":"kubernetes/kops","slug":"error-writing-to-stdout-v-8ff780","errorCode":null,"errorMessage":"error writing to stdout: %v","messagePattern":"error writing to stdout: (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/kops/get_cluster.go","lineNumber":272,"sourceCode":"\t\t}\n\t}\n\n\tif !singleObject {\n\t\tif _, err := fmt.Fprint(out, \"]\"); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\treturn nil\n}\n\n// fullOutputYAML outputs the marshalled JSON of a list of clusters and instance groups.  It will handle\n// nils for clusters and instanceGroups slices.\nfunc fullOutputYAML(out io.Writer, args ...runtime.Object) error {\n\tfor i, obj := range args {\n\t\tif i != 0 {\n\t\t\tif err := writeYAMLSep(out); err != nil {\n\t\t\t\treturn fmt.Errorf(\"error writing to stdout: %v\", err)\n\t\t\t}\n\t\t}\n\t\tif err := marshalToWriter(obj, marshalYaml, out); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc fullClusterSpecs(ctx context.Context, vfsContext *vfs.VFSContext, clusters []*kopsapi.Cluster) ([]*kopsapi.Cluster, error) {\n\tvar fullSpecs []*kopsapi.Cluster\n\tfor _, cluster := range clusters {\n\t\tconfigBase, err := registry.ConfigBase(vfsContext, cluster)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"error reading full cluster spec for %q: %v\", cluster.ObjectMeta.Name, err)\n\t\t}\n\t\tconfigPath := configBase.Join(registry.PathClusterCompleted)\n\t\tb, err := configPath.ReadFile(ctx)","sourceCodeStart":254,"sourceCodeEnd":290,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/cmd/kops/get_cluster.go#L254-L290","documentation":"fullOutputYAML serializes each runtime.Object to the output writer, emitting a YAML '---' separator between objects. If writing a separator fails (broken/closed stdout, disk full on redirected output, EPIPE), it wraps the underlying write error as 'error writing to stdout: %v'.","triggerScenarios":"`kops get clusters -o yaml` piped into a program that closes the pipe early (SIGPIPE/EPIPE), or output redirected to a full/unwritable target.","commonSituations":"`kops get -o yaml | head` closing the pipe; CI logs to a full tmpfs; stdout redirected to a read-only file or closed descriptor.","solutions":["Check that stdout's destination is writable and has free space.","Avoid piping into tools that exit early (e.g. `head`); capture full output or use `sed -n '1,Np'` alternatives that consume all input.","Inspect the wrapped error (%v) for the underlying errno (EPIPE, ENOSPC, EBADF) and fix accordingly.","Rerun without redirection to confirm kops itself is healthy."],"exampleFix":"// before\nkops get clusters -o yaml | head -5\n// after\nkops get clusters -o yaml > out.yaml && head -5 out.yaml","handlingStrategy":"fallback","validationCode":"# ensure stdout target is writable before piping\ndf -h \"${OUTDIR:-/tmp}\" | awk 'NR==2 && $4+0 < 1 {exit 1}' || { echo \"insufficient disk\" >&2; exit 1; }","typeGuard":"null","tryCatchPattern":"if ! kops get clusters -o yaml > out.yaml 2>err.txt; then\n  grep -q 'error writing to stdout' err.txt && echo \"stdout target failed: $(cat err.txt)\" || cat err.txt\nfi","preventionTips":["Write YAML/JSON output to a file instead of pipes that may close early.","Avoid `| head`/`| grep -m1` on kops output; process the full stream.","Monitor disk space on CI runners that redirect kops output to disk."],"tags":["io","stdout","yaml"],"backgroundTag":"broken-pipe-stdout","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"}