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

  1. For detached runs redirect stderr to a file so no write ever hits the dead pts: `flow ... 2>flow.log < /dev/null &`
  2. Re-run the command in a live terminal / fresh session
  3. 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

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


AI-assisted analysis of facebook/flow@f88ac94bcf (2026-08-20). Data as JSON: /api/errors/2fbc02654e0970ca. Report an issue: GitHub.