gleam-lang/gleam · warning
Final result error writing
Error message
Final result error writing
What it means
When the gleam CLI main function finishes with an Err, it pretty-prints the error to stderr and uses .expect("Final result error writing") on the print operation. If writing to stderr fails, this panics. It only triggers while already reporting a failure, so it compounds an existing error.
Solutions
- Ensure stderr is writable and the consuming pipe/process is still alive when running gleam commands
- Fix the underlying command failure first — this panic only occurs while reporting another error
- Avoid closing/redirecting stderr in CI wrappers that run gleam
- Report a broken-pipe scenario upstream if it happens in normal terminal use
Example fix
// before $ gleam build 2>&1 | head -1 # downstream closes the pipe early // after $ gleam build 2>&1 | tee build.log # keep the consumer alive while gleam writes
Defensive patterns
Strategy: try-catch
Validate before calling
fn stderr_is_writable() -> bool {
use std::io::Write;
std::io::stderr().flush().is_ok()
} Try / catch
if let Err(e) = write_stderr(&buffer) {
eprintln!("could not report error: {}", e);
std::process::exit(1);
} Prevention
- Do not close or early-exit consumers of gleam's stderr pipe
- Avoid 2>/dev/null variants in restricted sandboxes
- Fix the root command failure first
- Use tee instead of short-lived pipes when capturing output
When it happens
Trigger: The command failed (main returned Err), and stderr.print(&buffer) fails — typically because stderr is closed, redirected to a file/pipe that is full or unwritable, or the terminal detached.
Common situations: Running `gleam build 2>/dev/null` in environments where /dev/null write fails, CI runners with closed stderr descriptors, piping gleam output to a process that exited early (broken pipe), or a full disk when redirecting output to a file.
Related errors
AI-assisted analysis of gleam-lang/gleam@49f8762da5 (2026-09-14).
Data as JSON: /api/errors/35aaec8a4f9e58ae.
Report an issue: GitHub.
Appendix: source
Thrown at compiler-cli/src/lib.rs:968
version: String,
},
}
pub fn main() {
initialise_logger();
panic::add_handler();
let stderr = cli::stderr_buffer_writer();
let result = get_current_directory()
.and_then(|working_directory| Command::parse().run(working_directory));
match result {
Ok(_) => {
tracing::info!("Successfully completed");
}
Err(error) => {
tracing::error!(error = ?error, "Failed");
let mut buffer = stderr.buffer();
error.pretty(&mut buffer);
stderr.print(&buffer).expect("Final result error writing");
std::process::exit(1);
}
}
}
fn command_check(paths: &ProjectPaths, target: Option<Target>) -> Result<()> {
let _ = build::main(
paths,
Options {
root_target_support: TargetSupport::Enforced,
warnings_as_errors: false,
codegen: Codegen::DepsOnly,
compile: Compile::All,
mode: Mode::Dev,
target,
no_print_progress: false,
erlang_output: ErlangOutput::Binary,
},View on GitHub (pinned to 49f8762da5)