facebook/flow · error
failed to write cli errors
Error message
failed to write cli errors
What it means
Non-JSON path of check-contents: when the server returns ERRORS and --json is not set, cli_output::print_errors renders human-readable diagnostics (with strip-root and offset-kind adjustments) to locked stdout. The .expect() panics on the first failing write. With large error reports this is the classic EPIPE crash: Rust disables SIGPIPE, so `| head` closing the pipe early turns the next formatted write into an Err.
Source
Thrown at rust_port/crates/flow_cli/src/check_contents_command.rs:168
errors,
warnings,
suppressed_errors,
} => {
if json {
print_json(&errors, &warnings, &suppressed_errors)
} else {
let stdout = std::io::stdout();
let mut out = stdout.lock();
flow_common_errors::error_utils::cli_output::print_errors(
&mut out,
&error_flags,
&stdin_file,
strip_root.as_deref(),
&errors,
&warnings,
None,
)
.expect("failed to write cli errors");
out.flush().expect("failed to flush cli errors");
// Return a successful exit code if there were only warnings.
flow_common_exit_status::exit(command_utils::get_check_or_status_exit_code(
&errors,
&warnings,
error_flags.max_warnings,
))
}
}
server_prot::response::StatusResponse::NO_ERRORS => {
if json {
print_json(
&ConcreteLocPrintableErrorSet::empty(),
&ConcreteLocPrintableErrorSet::empty(),
&[],
)
} else {
let stdout = std::io::stdout();View on GitHub (pinned to f88ac94bcf)
Solutions
- Buffer with cat (`flow check-contents file.js | cat | head -50`) or page a saved file (`flow check-contents file.js > errors.txt; less errors.txt`)
- Take the full output and filter it afterwards instead of streaming into an early-exiting reader
- Free space / fix the redirect target if writing to a file or device
- Maintainer: match the Result and exit(141) on BrokenPipe instead of expect
Example fix
// before
flow_common_errors::error_utils::cli_output::print_errors(&mut out, /* ... */)
.expect("failed to write cli errors");
// after
if let Err(e) = flow_common_errors::error_utils::cli_output::print_errors(&mut out, /* ... */) {
if e.kind() == std::io::ErrorKind::BrokenPipe {
std::process::exit(141);
}
panic!("failed to write cli errors: {e}");
} Defensive patterns
Strategy: try-catch
Validate before calling
// Spawn wrapper: page a SAVED report, never the live stream: // flow check-contents file.js > errors.txt && less errors.txt
Try / catch
if let Err(e) = cli_output::print_errors(&mut out, /* ... */) {
if e.kind() == std::io::ErrorKind::BrokenPipe {
std::process::exit(141);
}
panic!("failed to write cli errors: {e}");
} Prevention
- Page saved files instead of piping live error reports into less/head
- Raise or remove line-count filters on diagnostics output
- Treat any `flow ... | head` in scripts as a latent broken-pipe crash and buffer it
When it happens
Trigger: `flow check-contents file.js | head -50` on a file producing hundreds of errors; piping the report into `less` and quitting with `q` while output still streams; stdout redirected to a full disk.
Common situations: Developers paging through large error reports and quitting early; CI scripts sampling the first N lines of diagnostics; output redirected to a nearly-full volume.
Related errors
- failed to write json errors
- failed to flush json errors
- failed to flush cli errors
- failed to write success output
- failed to flush success output
AI-assisted analysis of facebook/flow@f88ac94bcf (2026-08-20).
Data as JSON: /api/errors/b33a3ceab895622a.
Report an issue: GitHub.