{"record":{"id":"b33a3ceab895622a","repo":"facebook/flow","slug":"failed-to-write-cli-errors","errorCode":null,"errorMessage":"failed to write cli errors","messagePattern":"failed to write cli errors","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"rust_port/crates/flow_cli/src/check_contents_command.rs","lineNumber":168,"sourceCode":"            errors,\n            warnings,\n            suppressed_errors,\n        } => {\n            if json {\n                print_json(&errors, &warnings, &suppressed_errors)\n            } else {\n                let stdout = std::io::stdout();\n                let mut out = stdout.lock();\n                flow_common_errors::error_utils::cli_output::print_errors(\n                    &mut out,\n                    &error_flags,\n                    &stdin_file,\n                    strip_root.as_deref(),\n                    &errors,\n                    &warnings,\n                    None,\n                )\n                .expect(\"failed to write cli errors\");\n                out.flush().expect(\"failed to flush cli errors\");\n                // Return a successful exit code if there were only warnings.\n                flow_common_exit_status::exit(command_utils::get_check_or_status_exit_code(\n                    &errors,\n                    &warnings,\n                    error_flags.max_warnings,\n                ))\n            }\n        }\n        server_prot::response::StatusResponse::NO_ERRORS => {\n            if json {\n                print_json(\n                    &ConcreteLocPrintableErrorSet::empty(),\n                    &ConcreteLocPrintableErrorSet::empty(),\n                    &[],\n                )\n            } else {\n                let stdout = std::io::stdout();","sourceCodeStart":150,"sourceCodeEnd":186,"githubUrl":"https://github.com/facebook/flow/blob/f88ac94bcf6992f5d5a158854d94613ebb92c6e6/rust_port/crates/flow_cli/src/check_contents_command.rs#L150-L186","documentation":"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.","triggerScenarios":"`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.","commonSituations":"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.","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"],"exampleFix":"// before\nflow_common_errors::error_utils::cli_output::print_errors(&mut out, /* ... */)\n    .expect(\"failed to write cli errors\");\n\n// after\nif let Err(e) = flow_common_errors::error_utils::cli_output::print_errors(&mut out, /* ... */) {\n    if e.kind() == std::io::ErrorKind::BrokenPipe {\n        std::process::exit(141);\n    }\n    panic!(\"failed to write cli errors: {e}\");\n}","handlingStrategy":"try-catch","validationCode":"// Spawn wrapper: page a SAVED report, never the live stream:\n// flow check-contents file.js > errors.txt && less errors.txt","typeGuard":null,"tryCatchPattern":"if let Err(e) = cli_output::print_errors(&mut out, /* ... */) {\n    if e.kind() == std::io::ErrorKind::BrokenPipe {\n        std::process::exit(141);\n    }\n    panic!(\"failed to write cli errors: {e}\");\n}","preventionTips":["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"],"tags":["rust","flow-cli","stdout","broken-pipe","diagnostics","panic"],"backgroundTag":"broken-pipe","analyzedSha":"f88ac94bcf6992f5d5a158854d94613ebb92c6e6","analyzedAt":"2026-08-20T10:41:37.992Z","schemaVersion":2},"datasetVersion":"2026-08-23T11:17:13.642Z"}