{"record":{"id":"13850deaf8e01c3a","repo":"facebook/flow","slug":"failed-to-flush-spinner-status-13850d","errorCode":null,"errorMessage":"failed to flush spinner status","messagePattern":"failed to flush spinner status","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"rust_port/crates/flow_command_utils/src/lib.rs","lineNumber":2923,"sourceCode":"\n    fn print_status(msg: &str, enabled: bool, use_spinner: bool) {\n        if !enabled {\n            return;\n        }\n\n        let stderr = std::io::stderr();\n        let mut stderr = stderr.lock();\n        if use_spinner && stderr.is_terminal() {\n            if flow_utils_tty::spinner_used() {\n                flow_utils_tty::print_clear_line(&mut stderr)\n                    .expect(\"failed to clear spinner line\");\n            }\n            write!(stderr, \"{}: {}\", msg, flow_utils_tty::spinner(false))\n                .expect(\"failed to write spinner status\");\n            stderr.flush().expect(\"failed to flush spinner status\");\n        } else {\n            writeln!(stderr, \"{}\", msg).expect(\"failed to write spinner status\");\n            stderr.flush().expect(\"failed to flush spinner status\");\n        }\n    }\n\n    // Waits for a response over the socket. If the connection dies, this will throw an exception\n    fn wait_for_response(\n        stream: &mut flow_common_socket::socket::SocketStream,\n        show_progress: bool,\n        emoji: bool,\n        _root: &std::path::Path,\n    ) -> Result<server_prot::response::Response, ()> {\n        let use_emoji = flow_utils_tty::supports_emoji() && emoji;\n        stream.set_read_timeout(None).map_err(|_| ())?;\n        loop {\n            let response: Result<MonitorToClientMessage, _> =\n                flow_parser::loc::with_full_source_serde(|| {\n                    bincode::serde::decode_from_std_read(\n                        &mut *stream,\n                        bincode::config::legacy()","sourceCodeStart":2905,"sourceCodeEnd":2941,"githubUrl":"https://github.com/facebook/flow/blob/5c865861998a8ccb7dbc82b0c1f511e9ef60c3d9/rust_port/crates/flow_command_utils/src/lib.rs#L2905-L2941","documentation":"While showing progress for a long-running server command, the client writes spinner status to stderr and flushes it; if the flush fails, it panics with this message. This almost always means stderr is no longer writable (e.g. the terminal/pipe was closed).","triggerScenarios":"stderr.flush() returns Err inside the progress printing helper — stderr redirected to a closed pipe or a full/unwritable file while a spinner is active.","commonSituations":"Running flow in CI where output pipes are closed early (`| head`), detached background jobs whose stderr fd was closed, or docker containers with detached TTYs.","solutions":["Ensure stderr remains open for the duration of the flow command; avoid piping into consumers that exit early (e.g. `flow ... | head`).","Disable progress/spinner output via non-TTY/stdout redirection or CI-appropriate flags so the spinner path is skipped.","Check disk space / file permissions if stderr is redirected to a file."],"exampleFix":"// before\nflow check | head -n 5   # closes pipe early\n// after\nflow check > flow.log 2>&1; head -n 5 flow.log","handlingStrategy":"fallback","validationCode":"test -w /dev/stderr || echo 'stderr not writable; disable spinner/progress output'","typeGuard":null,"tryCatchPattern":"flow check > flow.log 2>&1 || { cat flow.log; exit 1; }","preventionTips":["Don't pipe flow output into consumers that exit early (head, grep -m1).","Redirect to files in CI instead of live pipes.","Ensure sufficient disk space for redirected output."],"tags":["io","stderr","spinner","broken-pipe"],"backgroundTag":"broken-pipe","analyzedSha":"5c865861998a8ccb7dbc82b0c1f511e9ef60c3d9","analyzedAt":"2026-09-08T04:32:53.179Z","contentChangedAt":"2026-09-08T04:32:53.179Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}