facebook/flow · error

failed to flush cli errors

Error message

failed to flush cli errors

What it means

Flush of the human-readable error report in check-contents (no --json). Identical mechanics to the JSON flush variant: the print_errors writes land in the stdout buffer while the reader is still alive, the reader then exits (head done, grep -q matched), and the explicit out.flush() returns EPIPE or ENOSPC, which the .expect() turns into a panic after the report was already emitted.

Source

Thrown at rust_port/crates/flow_cli/src/check_contents_command.rs:169

            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();
                let mut out = stdout.lock();

View on GitHub (pinned to f88ac94bcf)

Solutions

  1. Capture to a file first: `flow check-contents file.js > out.txt` then run grep/head on the file
  2. Add `| cat` as the final buffering stage, or drop the early-exiting consumer
  3. Check/free disk space when redirecting to files
  4. Maintainer: exit quietly (141) on BrokenPipe at the flush instead of panicking

Example fix

// before
out.flush().expect("failed to flush cli errors");

// after
if let Err(e) = out.flush() {
    if e.kind() == std::io::ErrorKind::BrokenPipe {
        std::process::exit(141);
    }
    panic!("failed to flush cli errors: {e}");
}
Defensive patterns

Strategy: try-catch

Try / catch

if let Err(e) = out.flush() {
    if e.kind() == std::io::ErrorKind::BrokenPipe {
        std::process::exit(141);
    }
    panic!("failed to flush cli errors: {e}");
}

Prevention

When it happens

Trigger: `flow check-contents file.js | grep -m1 "Error"` — grep exits after the first matching error line, the flush then gets EPIPE; redirect to a filesystem that becomes full between the writes and the flush.

Common situations: Scripts probing CLI output with grep -q/-m1/head; pipelines whose downstream stage fails fast and closes its stdin; disk-full CI runners.

Related errors


AI-assisted analysis of facebook/flow@f88ac94bcf (2026-08-20). Data as JSON: /api/errors/a967f85f81b061c6. Report an issue: GitHub.