{"record":{"id":"f9a1c76cafd88d61","repo":"facebook/flow","slug":"failed-to-flush-not-covered-output","errorCode":null,"errorMessage":"failed to flush not-covered output","messagePattern":"failed to flush not-covered output","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"rust_port/crates/flow_cli/src/check_contents_command.rs","lineNumber":204,"sourceCode":"                let stdout = std::io::stdout();\n                let mut out = stdout.lock();\n                writeln!(out, \"No errors!\").expect(\"failed to write success output\");\n                out.flush().expect(\"failed to flush success output\");\n            }\n            flow_common_exit_status::exit(flow_common_exit_status::FlowExitStatus::NoError)\n        }\n        server_prot::response::StatusResponse::NOT_COVERED => {\n            if json {\n                print_json(\n                    &ConcreteLocPrintableErrorSet::empty(),\n                    &ConcreteLocPrintableErrorSet::empty(),\n                    &[],\n                )\n            } else {\n                let stdout = std::io::stdout();\n                let mut out = stdout.lock();\n                writeln!(out, \"File is not @flow!\").expect(\"failed to write not-covered output\");\n                out.flush().expect(\"failed to flush not-covered output\");\n            }\n            flow_common_exit_status::exit(flow_common_exit_status::FlowExitStatus::NoError)\n        }\n    }\n}\n\npub(crate) fn command() -> command_spec::Command {\n    command_spec::command(spec(), main)\n}\n","sourceCodeStart":186,"sourceCodeEnd":214,"githubUrl":"https://github.com/facebook/flow/blob/f88ac94bcf6992f5d5a158854d94613ebb92c6e6/rust_port/crates/flow_cli/src/check_contents_command.rs#L186-L214","documentation":"Flush after the 'File is not @flow!' line in check-contents. Same single-line race as the success-message flush: the writeln fits in the pipe buffer, the reader then exits and closes the pipe, and this out.flush() returns EPIPE (or ENOSPC on a full redirect target); the .expect() turns it into a panic instead of the intended NoError exit.","triggerScenarios":"`flow check-contents module.js | grep -q 'not @flow'` — grep exits after the match, flush gets EPIPE; consumer exiting between write and flush; flushing into a full filesystem.","commonSituations":"Scripts probing for the not-covered message with grep -q; pipelines with short-lived consumers; disk-full CI environments.","solutions":["Rely on the exit code / JSON output instead of text probing","Capture to a file first, then grep the file","Add a buffering `| cat` stage so the flush always succeeds","Maintainer: exit quietly (141) on BrokenPipe at the flush instead of expect"],"exampleFix":"// before\nout.flush().expect(\"failed to flush not-covered output\");\n\n// after\nif let Err(e) = out.flush() {\n    if e.kind() == std::io::ErrorKind::BrokenPipe {\n        std::process::exit(141);\n    }\n    panic!(\"failed to flush not-covered output: {e}\");\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"if let Err(e) = out.flush() {\n    if e.kind() == std::io::ErrorKind::BrokenPipe {\n        std::process::exit(141);\n    }\n    panic!(\"failed to flush not-covered output: {e}\");\n}","preventionTips":["Rely on exit codes or --json status instead of text probes","Capture output to files before grepping","Keep pipeline consumers alive until EOF"],"tags":["rust","flow-cli","stdout","broken-pipe","flush","panic"],"backgroundTag":"broken-pipe","analyzedSha":"f88ac94bcf6992f5d5a158854d94613ebb92c6e6","analyzedAt":"2026-08-20T10:41:37.992Z","schemaVersion":2},"datasetVersion":"2026-08-23T11:17:13.642Z"}