facebook/flow · error
failed to write success output
Error message
failed to write success output
What it means
Happy path of check-contents: the server answers StatusResponse::NO_ERRORS and, without --json, the CLI writes the single line 'No errors!' to locked stdout. Even one writeln can fail: once the pipe's read end is fully closed (consumer exited or fd closed), any write returns EPIPE immediately, so the .expect() panics before the NoError exit status is set.
Source
Thrown at rust_port/crates/flow_cli/src/check_contents_command.rs:188
// 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();
writeln!(out, "No errors!").expect("failed to write success output");
out.flush().expect("failed to flush success output");
}
flow_common_exit_status::exit(flow_common_exit_status::FlowExitStatus::NoError)
}
server_prot::response::StatusResponse::NOT_COVERED => {
if json {
print_json(
&ConcreteLocPrintableErrorSet::empty(),
&ConcreteLocPrintableErrorSet::empty(),
&[],
)
} else {
let stdout = std::io::stdout();
let mut out = stdout.lock();
writeln!(out, "File is not @flow!").expect("failed to write not-covered output");
out.flush().expect("failed to flush not-covered output");
}
flow_common_exit_status::exit(flow_common_exit_status::FlowExitStatus::NoError)View on GitHub (pinned to f88ac94bcf)
Solutions
- Capture to a file and test the file: `flow check-contents file.js > out.txt; test $? -eq 0`
- Make the downstream consumer read until EOF instead of exiting early
- Ensure the CLI's stdout is a live pipe or file (never closed) in wrappers
- Maintainer: match the writeln result and exit(141) on BrokenPipe instead of expect
Example fix
// before
writeln!(out, "No errors!").expect("failed to write success output");
// after
if let Err(e) = writeln!(out, "No errors!") {
if e.kind() == std::io::ErrorKind::BrokenPipe {
std::process::exit(141);
}
panic!("failed to write success output: {e}");
} Defensive patterns
Strategy: try-catch
Validate before calling
// Consumers should read until EOF rather than exit early: // (pattern for a wrapper that inspects output then decides) // flow check-contents file.js > out.txt # always drains the writer
Try / catch
if let Err(e) = writeln!(out, "No errors!") {
if e.kind() == std::io::ErrorKind::BrokenPipe {
std::process::exit(141);
}
panic!("failed to write success output: {e}");
} Prevention
- Branch on exit codes instead of matching on streamed output text
- Do not wrap the CLI in pipelines whose stages may exit before reading
- Keep stdout attached to a file or a durable reader in automation
When it happens
Trigger: `flow check-contents file.js | true` or a fast-failing validation step that exits without reading; a consumer that exits before the CLI's write lands (race); stdout closed via `>&-` or an invalid redirect.
Common situations: Scripts using `cmd | grep -q SomethingElse` patterns where the probe exits; wrappers that spawn the CLI but close the pipe early on their own error paths; sandboxed environments closing stdout fds.
Related errors
- failed to write json errors
- failed to flush json errors
- failed to write cli errors
- failed to flush cli errors
- failed to flush success output
AI-assisted analysis of facebook/flow@f88ac94bcf (2026-08-20).
Data as JSON: /api/errors/98a0fec358b2d0a6.
Report an issue: GitHub.