{"record":{"id":"ac2c4f378bf7f0a3","repo":"gleam-lang/gleam","slug":"write-new-line-after-diagnostic","errorCode":null,"errorMessage":"write new line after diagnostic","messagePattern":"write new line after diagnostic","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"compiler-core/src/error.rs","lineNumber":1007,"sourceCode":"        _ if value / 10 == 1 => format!(\"{value}th\"),\n        1 => format!(\"{value}st\"),\n        2 => format!(\"{value}nd\"),\n        3 => format!(\"{value}rd\"),\n        _ => format!(\"{value}th\"),\n    }\n}\n\nimpl Error {\n    pub fn pretty_string(&self) -> String {\n        let mut nocolor = Buffer::no_color();\n        self.pretty(&mut nocolor);\n        String::from_utf8(nocolor.into_inner()).expect(\"Error printing produced invalid utf8\")\n    }\n\n    pub fn pretty(&self, buffer: &mut Buffer) {\n        for diagnostic in self.to_diagnostics() {\n            diagnostic.write(buffer);\n            writeln!(buffer).expect(\"write new line after diagnostic\");\n        }\n    }\n\n    pub fn skipped_files_diagnostics(&self) -> HashMap<Utf8PathBuf, Diagnostic> {\n        let Error::Type {\n            skipped_modules, ..\n        } = self\n        else {\n            return HashMap::new();\n        };\n\n        skipped_modules\n            .iter()\n            .map(|skipped_module| {\n                let text = match &skipped_module.reason {\n                    SkipReason::DependencyHasError { .. } => {\n                        \"The current module cannot be analysed because this \\\nimported module has errors.\"","sourceCodeStart":989,"sourceCodeEnd":1025,"githubUrl":"https://github.com/gleam-lang/gleam/blob/49f8762da595eb3c8f576656a4200a142ca188c9/compiler-core/src/error.rs#L989-L1025","documentation":"In `Error::pretty`, each rendered diagnostic is written to the output buffer followed by `writeln!(buffer).expect(\"write new line after diagnostic\")`. `writeln!` returns `Err` if the underlying writer fails; since the buffer is an in-memory `codespan` `Buffer` this should be infallible, so the `expect` asserts the invariant that writing to the buffer never fails. A panic here means the writer implementation or buffer state is broken.","triggerScenarios":"`writeln!(buffer)` returns `Err` — realistically only when `pretty` is (or becomes) callable with a custom `Buffer`-like writer whose `write` implementation errors (disk full, closed pipe such as `gleam build | head`, or a mocked writer in tests that intentionally fails).","commonSituations":"Piping compiler output to a short-lived reader (e.g. `gleam check | head -1`) where the pipe is closed (broken pipe), or embedding the library with a custom buffer backed by a failing sink.","solutions":["Avoid piping the compiler output into commands that close the pipe early, or ignore SIGPIPE (`trap '' PIPE`)/use `std::io::sink`-safe output paths","Upgrade Gleam — CLI output writing has been progressively hardened against broken pipes","If embedding, pass the standard `Buffer::no_color()`/`Buffer::ansi()` which write to memory and cannot fail"],"exampleFix":"// before\nwriteln!(buffer).expect(\"write new line after diagnostic\");\n// after\nif writeln!(buffer).is_err() {\n    return; // downstream writer is gone; stop rendering diagnostics\n}","handlingStrategy":"try-catch","validationCode":"// check output sink writability before running the compiler, e.g. avoid closed pipes:\n// gleam build | head   <-- avoid; use full output redirect instead","typeGuard":null,"tryCatchPattern":"match std::process::Command::new(\"gleam\").arg(\"build\").output() {\n    Ok(out) => print!(\"{}\", String::from_utf8_lossy(&out.stdout)),\n    Err(e) => eprintln!(\"compiler output failed: {e}\"), // includes broken-pipe cases\n}","preventionTips":["Do not pipe compiler output into commands that exit early (head, less -F); capture to a file instead","Handle SIGPIPE in wrapper scripts (trap '' PIPE) or write diagnostics to stderr","Embed with standard Buffer types, which write to memory and cannot fail"],"tags":["rust","compiler","io","diagnostics","broken-pipe"],"backgroundTag":"broken-pipe","analyzedSha":"49f8762da595eb3c8f576656a4200a142ca188c9","analyzedAt":"2026-09-14T11:14:59.388Z","contentChangedAt":"2026-09-14T11:14:59.388Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}