facebook/flow · error
failed to write spinner status
Error message
failed to write spinner status
What it means
In eprintf_with_spinner's terminal branch, after clearing the spinner line the CLI writes '<message>: <spinner-frame>' to stderr (spinner(false) returns the next ASCII spinner frame). If the terminal's pts master has closed, this write returns EIO and the .expect() panics mid-status-line, typically during server connect/retry messages.
Source
Thrown at rust_port/crates/flow_cli/src/command_utils.rs:3007
&command,
stream,
bincode::config::legacy()
.with_limit::<{ flow_commands_connect::command_connect_simple::MAX_FRAME_BYTES }>(),
)
})?;
Ok(())
}
fn eprintf_with_spinner(msg: &str) {
let stderr = std::io::stderr();
let mut stderr = stderr.lock();
if stderr.is_terminal() {
if flow_utils_tty::spinner_used() {
flow_utils_tty::print_clear_line(&mut stderr)
.expect("failed to clear spinner line");
}
write!(stderr, "{}: {}", msg, flow_utils_tty::spinner(false))
.expect("failed to write spinner status");
stderr.flush().expect("failed to flush spinner status");
} else {
writeln!(stderr, "{}", msg).expect("failed to write spinner status");
stderr.flush().expect("failed to flush spinner status");
}
}
// Waits for a response over the socket. If the connection dies, this will throw an exception
fn wait_for_response(
stream: &mut flow_common_socket::socket::SocketStream,
quiet: bool,
emoji: bool,
_root: &std::path::Path,
) -> Result<server_prot::response::Response, ()> {
let use_emoji = flow_utils_tty::supports_emoji() && emoji;
stream.set_read_timeout(None).map_err(|_| ())?;
loop {
let response: Result<MonitorToClientMessage, _> =View on GitHub (pinned to f88ac94bcf)
Solutions
- Redirect stderr to a file for detached runs: `flow ... 2>flow.log &`
- Run the command inside a session that stays alive (tmux attach kept open, ssh kept connected)
- Maintainer: treat status-line writes as best-effort (ignore or log-and-continue on Err) instead of expect
Example fix
// before
write!(stderr, "{}: {}", msg, flow_utils_tty::spinner(false))
.expect("failed to write spinner status");
// after
let _ = write!(stderr, "{}: {}", msg, flow_utils_tty::spinner(false)); Defensive patterns
Strategy: fallback
Try / catch
// Progress output is best-effort; skip silently when stderr is dead
let _ = write!(stderr, "{}: {}", msg, flow_utils_tty::spinner(false)); Prevention
- Keep the owning terminal/session alive for the whole run (tmux/ssh)
- Redirect stderr to a file when detaching processes
- Disable interactive progress (quiet mode) in non-interactive automation
When it happens
Trigger: The controlling terminal/ssh session dies (with SIGHUP ignored or under nohup) while the CLI is printing connect progress such as 'Please hold' or retry notices; a tmux pane holding the process is killed; stderr redirected to a pts that has been recycled.
Common situations: Disconnecting from long-running remote checks; automation that detaches sessions mid-run; pty-based harnesses torn down early.
Related errors
- failed to clear spinner line
- failed to flush spinner status
- failed to write cli errors
- failed to flush cli errors
- failed to get current directory
AI-assisted analysis of facebook/flow@f88ac94bcf (2026-08-20).
Data as JSON: /api/errors/d0ddc81f90e727d0.
Report an issue: GitHub.