{"record":{"id":"1286f47cca7208aa","repo":"can1357/oh-my-pi","slug":"error-writing-standard-output-err","errorCode":null,"errorMessage":"error writing 'standard output': {err}","messagePattern":"error writing 'standard output': (.+?)","errorType":"error_code","errorClass":"io::Error","httpStatus":null,"severity":"error","filePath":"crates/pi-builtins/src/head.rs","lineNumber":1151,"sourceCode":"\t\toptions.quiet = matches.get_flag(options::QUIET);\n\t\toptions.verbose = matches.get_flag(options::VERBOSE);\n\t\toptions.line_ending = LineEnding::from_zero_flag(matches.get_flag(options::ZERO));\n\t\toptions.presume_input_pipe = matches.get_flag(options::PRESUME_INPUT_PIPE);\n\n\t\toptions.mode = Mode::from(matches)?;\n\n\t\toptions.files = match matches.get_many::<OsString>(options::FILES) {\n\t\t\tSome(v) => v.cloned().collect(),\n\t\t\tNone => vec![OsString::from(\"-\")],\n\t\t};\n\n\t\tOk(options)\n\t}\n}\n\n#[inline]\nfn wrap_in_stdout_error(err: io::Error) -> io::Error {\n\tio::Error::new(err.kind(), format!(\"error writing 'standard output': {err}\"))\n}\n\n\nfn read_n_bytes(input: impl Read, output: &mut impl Write, n: u64) -> io::Result<u64> {\n\tlet mut reader = input.take(n);\n\tlet bytes_written = io::copy(&mut reader, output).map_err(wrap_in_stdout_error)?;\n\toutput.flush().map_err(wrap_in_stdout_error)?;\n\tOk(bytes_written)\n}\n\nfn read_n_lines(\n\tinput: &mut impl io::BufRead,\n\toutput: &mut impl Write,\n\tn: u64,\n\tseparator: u8,\n) -> io::Result<u64> {\n\tlet mut reader = take_lines(input, n, separator);\n\tlet bytes_written = io::copy(&mut reader, output).map_err(wrap_in_stdout_error)?;","sourceCodeStart":1133,"sourceCodeEnd":1169,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/crates/pi-builtins/src/head.rs#L1133-L1169","documentation":"When writing head's output to stdout fails, the io::Error is re-wrapped with the message \"error writing 'standard output': {err}\" preserving the original error kind. This mirrors GNU coreutils' phrasing and clearly attributes mid-stream write failures (broken pipe, ENOSPC, EIO) to stdout rather than input reading.","triggerScenarios":"Running the head builtin when stdout is a closed pipe (consumer exited, SIGPIPE/EPIPE), a full disk (ENOSPC) while redirecting, or an otherwise failing output descriptor during io::copy in read_n_bytes/read_n_lines.","commonSituations":"`head big.log | head -n 1` where the downstream consumer closes the pipe early; cron jobs with redirected stdout to a full filesystem; containers with closed/disconnected stdout.","solutions":["Ensure the downstream consumer of the pipe stays open long enough, or restructure the pipeline","Check available disk space (df -h) when output is redirected to a file","Inspect the wrapped inner err for the OS-level cause (EPIPE vs ENOSPC vs EIO)","In callers, match on the error kind to treat EPIPE as benign early-exit"],"exampleFix":"// before\nlet out = head_to_stdout(path, 10).unwrap(); // panics on EPIPE\n// after\nmatch head_to_stdout(path, 10) {\n\tOk(n) => /* ... */,\n\tErr(e) if e.kind() == io::ErrorKind::BrokenPipe => return Ok(()),\n\tErr(e) => return Err(e),\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"match head_result {\n\tErr(e) if e.kind() == io::ErrorKind::BrokenPipe => { /* consumer closed stdout; exit quietly */ }\n\tErr(e) if e.to_string().starts_with(\"error writing 'standard output'\") => {\n\t\teprintln!(\"stdout write failed: {e}\");\n\t}\n\tErr(e) => return Err(e),\n\tOk(v) => /* ... */,\n}","preventionTips":["Avoid pipelines where downstream consumers exit before upstream finishes; drain output if needed","Monitor disk space in environments where head output is redirected to files","Treat BrokenPipe as expected control flow in Unix pipelines, not a crash"],"tags":["rust","io","broken-pipe","stdout","thiserror"],"backgroundTag":"broken-pipe","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}