{"record":{"id":"441bb694fe72ec8d","repo":"gleam-lang/gleam","slug":"writing-warning-to-stderr","errorCode":null,"errorMessage":"Writing warning to stderr","messagePattern":"Writing warning to stderr","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"compiler-cli/src/fs.rs","lineNumber":894,"sourceCode":"            action: FileIoAction::Canonicalise,\n            kind: FileKind::File,\n            path: Utf8PathBuf::from(path),\n            err: Some(err.to_string()),\n        })\n        .map(|pb| Utf8PathBuf::from_path_buf(pb).expect(\"Non Utf8 Path\"))\n}\n\n#[derive(Debug, Clone, Copy)]\npub struct ConsoleWarningEmitter;\n\nimpl WarningEmitterIO for ConsoleWarningEmitter {\n    fn emit_warning(&self, warning: Warning) {\n        let buffer_writer = crate::cli::stderr_buffer_writer();\n        let mut buffer = buffer_writer.buffer();\n        warning.pretty(&mut buffer);\n        buffer_writer\n            .print(&buffer)\n            .expect(\"Writing warning to stderr\");\n    }\n}\n\n/// Returns root of Git repository in base path if it is initialised.\npub fn get_git_repository_root(mut path: Utf8PathBuf) -> Option<Utf8PathBuf> {\n    loop {\n        if path.join(\".git\").is_dir() {\n            return Some(path);\n        }\n\n        path = {\n            let path = path.parent()?;\n            path.into()\n        }\n    }\n}\n\n#[derive(Debug)]","sourceCodeStart":876,"sourceCodeEnd":912,"githubUrl":"https://github.com/gleam-lang/gleam/blob/15b07c783065c92bb016b1b74ed0995a5259850f/compiler-cli/src/fs.rs#L876-L912","documentation":"`ConsoleWarningEmitter::emit_warning` writes a formatted compiler warning to stderr via the `term` crate's buffer writer and calls `.expect(\"Writing warning to stderr\")`. If `print` fails (the underlying write to stderr errors), the process panics. Writing diagnostics is treated as infallible, so any stderr failure is fatal.","triggerScenarios":"Calling emit_warning when stderr cannot be written: closed/broken stderr pipe (e.g. `gleam build | head` causing SIGPIPE/EPIPE), stderr redirected to a full disk or an unwritable file, or stderr closed by the parent process.","commonSituations":"CI pipelines that close output streams early, piping gleam output into commands that exit before reading all output, containers with stdout/stderr wired to broken descriptors.","solutions":["Ensure the process consuming stderr keeps reading until gleam exits (avoid piping into commands that exit early, or use `stdbuf`/fully drain output).","Check the stderr destination is writable and has free disk space.","If piping, collect output to a file instead: `gleam build 2> warnings.log`.","In a fork, replace the expect with graceful handling (e.g. ignore write errors or log once)."],"exampleFix":"// before\nbuffer_writer.print(&buffer).expect(\"Writing warning to stderr\");\n// after\nif let Err(err) = buffer_writer.print(&buffer) {\n    eprintln!(\"failed to write warning: {err}\");\n}","handlingStrategy":"try-catch","validationCode":"// Check stderr is writable before emitting\nif !is_fd_writable(2) { eprintln!(\"stderr unavailable; dropping warning\"); return; }","typeGuard":null,"tryCatchPattern":"match buffer_writer.print(&buffer) {\n    Ok(()) => {}\n    Err(err) if err.kind() == std::io::ErrorKind::BrokenPipe => std::process::exit(0),\n    Err(err) => eprintln!(\"failed to write warning: {err}\"),\n}","preventionTips":["Avoid piping compiler output into commands that exit early (e.g. `| head`)","Redirect warnings to a file in CI instead of relying on a live stderr consumer","Ensure output destinations have free disk space","Handle BrokenPipe explicitly in long-running CLI tools"],"tags":["rust","stderr","panic","io"],"backgroundTag":"broken-pipe","analyzedSha":"15b07c783065c92bb016b1b74ed0995a5259850f","analyzedAt":"2026-09-14T11:14:59.388Z","contentChangedAt":"2026-09-14T11:14:59.388Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}