facebook/flow · error

failed to write not-covered output

Error message

failed to write not-covered output

What it means

NOT_COVERED branch of check-contents: the checked file lacks the `@flow` pragma (and --all was not passed), so the server reports not covered and the CLI writes the single line 'File is not @flow!' to stdout. The .expect() panics when that write fails — in practice when the pipe reader already exited (EPIPE) or stdout points to a full/closed target.

Source

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

            } 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)
        }
    }
}

pub(crate) fn command() -> flow_command_spec::Command {
    flow_command_spec::command(spec(), main)
}

View on GitHub (pinned to 5c86586199)

Solutions

  1. Capture to a file: `flow check-contents module.js > out.txt` and inspect it afterwards
  2. Keep the downstream consumer alive until EOF, or add `| cat` as a buffer
  3. Pass --all if you intend to check files without the @flow pragma, avoiding surprise output shape
  4. Maintainer: match the writeln result and exit(141) on BrokenPipe instead of expect

Example fix

// before
writeln!(out, "File is not @flow!").expect("failed to write not-covered output");

// after
if let Err(e) = writeln!(out, "File is not @flow!") {
    if e.kind() == std::io::ErrorKind::BrokenPipe {
        std::process::exit(141);
    }
    panic!("failed to write not-covered output: {e}");
}
Defensive patterns

Strategy: try-catch

Validate before calling

// Know the output shape up front: files without the @flow pragma
// (and no --all) produce 'File is not @flow!' — probe that on a saved file:
// flow check-contents module.js > out.txt; grep -F 'not @flow' out.txt

Try / catch

if let Err(e) = writeln!(out, "File is not @flow!") {
    if e.kind() == std::io::ErrorKind::BrokenPipe {
        std::process::exit(141);
    }
    panic!("failed to write not-covered output: {e}");
}

Prevention

When it happens

Trigger: `flow check-contents module.js | true` where module.js has no `@flow` comment and the consumer exits without reading; piping the result into a probe that exits on unrelated input; stdout closed or /dev/full.

Common situations: Batch scripts checking many files where some lack the pragma, piped into early-exiting filters; wrappers that close stdout early on their own error paths.

Related errors


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