facebook/flow · error
failed to clear spinner line
Error message
failed to clear spinner line
What it means
eprintf_with_spinner prints connect/status progress to stderr while the CLI talks to the flow server. When stderr is a terminal and the spinner animation has already drawn, flow_utils_tty::print_clear_line first emits the ANSI erase sequence "\r\x1b[0K" and flushes. Writing to a pts whose master side is gone returns EIO, so the .expect() panics while trying to redraw the spinner line.
Source
Thrown at rust_port/crates/flow_cli/src/command_utils.rs:3004
};
flow_parser::loc::with_full_source_serde(|| {
bincode::serde::encode_into_std_write(
&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;View on GitHub (pinned to f88ac94bcf)
Solutions
- For detached runs redirect stderr to a file so no write ever hits the dead pts: `flow ... 2>flow.log < /dev/null &`
- Re-run the command in a live terminal / fresh session
- Maintainer: make spinner cleanup best-effort — `let _ = print_clear_line(&mut stderr);` — since a failed UI redraw should never crash the CLI
Example fix
// before
flow_utils_tty::print_clear_line(&mut stderr)
.expect("failed to clear spinner line");
// after
// UI redraw is best-effort; never crash on a dead terminal
let _ = flow_utils_tty::print_clear_line(&mut stderr); Defensive patterns
Strategy: fallback
Try / catch
// UI redraw is best-effort: a dead terminal must not crash the CLI let _ = flow_utils_tty::print_clear_line(&mut stderr);
Prevention
- For detached runs, always redirect stderr to a file: `flow ... 2>flow.log < /dev/null &`
- Avoid pty-allocating wrappers (script -c) that exit before the wrapped command
- Treat every spinner/ANSI write as non-critical — ignore its Result in code you control
When it happens
Trigger: The CLI keeps running after its controlling terminal closed — ssh session dropped or terminal emulator quit while flow runs under nohup/disown with SIGHUP ignored — leaving stderr pointed at a dead pts; tmux/screen pane killed underneath the process; a pty-allocating wrapper (script -c) that exits early.
Common situations: Long checks left running over ssh that disconnects; CI wrappers allocating ptys that are torn down mid-run; terminal emulators crashing during long operations.
Related errors
- failed to write spinner status
- 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/2fbc02654e0970ca.
Report an issue: GitHub.