{"record":{"id":"c4b1dcb251c66e14","repo":"kubernetes/kops","slug":"error-writing-to-output-v-c4b1dc","errorCode":null,"errorMessage":"error writing to output: %v","messagePattern":"error writing to output: (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/kops/get_keypairs.go","lineNumber":244,"sourceCode":"\t\t\tif i.HasPrivateKey {\n\t\t\t\treturn \"*\"\n\t\t\t}\n\t\t\treturn \"\"\n\t\t})\n\t\tcolumnNames := []string{\"NAME\", \"ID\", \"ISSUED\", \"EXPIRES\"}\n\t\tif options.Distrusted {\n\t\t\tcolumnNames = append(columnNames, \"DISTRUSTED\")\n\t\t}\n\t\tcolumnNames = append(columnNames, \"PRIMARY\", \"HASPRIVATE\")\n\t\treturn t.Render(items, out, columnNames...)\n\n\tcase OutputYaml:\n\t\ty, err := yaml.Marshal(items)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"unable to marshal YAML: %v\", err)\n\t\t}\n\t\tif _, err := out.Write(y); err != nil {\n\t\t\treturn fmt.Errorf(\"error writing to output: %v\", err)\n\t\t}\n\tcase OutputJSON:\n\t\tj, err := json.Marshal(items)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"unable to marshal JSON: %v\", err)\n\t\t}\n\t\tif _, err := out.Write(j); err != nil {\n\t\t\treturn fmt.Errorf(\"error writing to output: %v\", err)\n\t\t}\n\n\tdefault:\n\t\treturn fmt.Errorf(\"unknown output format: %q\", options.Output)\n\t}\n\n\treturn nil\n}\n\nfunc completeGetKeypairs(ctx context.Context, f commandutils.Factory, options *GetKeypairsOptions, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {","sourceCodeStart":226,"sourceCodeEnd":262,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/cmd/kops/get_keypairs.go#L226-L262","documentation":"In RunGetKeypairs' OutputYaml branch, after a successful yaml.Marshal the resulting bytes are written to the output writer. If out.Write(y) fails — broken pipe to a downstream process, closed stream, or an unwritable output file — the error is wrapped as \"error writing to output: %v\".","triggerScenarios":"`kops get keypairs -o yaml` piped into a consumer that exits before reading everything (e.g. `| head`), or output redirected to a full/read-only file, causing the io.Writer to return an error.","commonSituations":"Piping into `head`, `grep -q`, or a script that closes stdin early (EPIPE); `--out` file on a full disk; CI log collector dropping the stream mid-write.","solutions":["Inspect the wrapped cause: EPIPE means the downstream consumer closed early — avoid `| head` or tolerate SIGPIPE.","Redirect to a file instead of a pipe to test whether the writer is the problem.","Check disk space/permissions if using an output file.","Retry on a plain terminal; if it still fails on a valid writer, report the underlying error upstream."],"exampleFix":"// before\nkops get keypairs -o yaml | head -5   # broken pipe\n// after\nkops get keypairs -o yaml > keypairs.yaml && head -5 keypairs.yaml","handlingStrategy":"try-catch","validationCode":"# ensure the destination is writable before streaming\n[ -w \"$(pwd)\" ] && [ \"$(df --output=avail -k . | tail -1)\" -gt 1024 ] || exit 2","typeGuard":null,"tryCatchPattern":"if err := runKops(\"get\", \"keypairs\", \"-o\", \"yaml\"); err != nil {\n\tif strings.Contains(err.Error(), \"error writing to output\") {\n\t\t// check wrapped cause for EPIPE; write to a file and retry once\n\t}\n\treturn err\n}","preventionTips":["Do not pipe YAML into commands that close stdin early.","Write to a temp file then post-process, rather than long pipelines.","Monitor disk space where --out files are written.","Differentiate EPIPE (benign consumer exit) from real I/O failures in wrappers."],"tags":["io","yaml-output","broken-pipe","cli"],"backgroundTag":"output-write-failed","analyzedSha":"4c8573c808a73d578c5eadc86d410646ea0b0d73","analyzedAt":"2026-09-05T04:13:19.212Z","contentChangedAt":"2026-09-05T04:13:19.212Z","schemaVersion":2},"datasetVersion":"2026-09-12T12:17:11.808Z"}