Hmbown/CodeWhale · error · anyhow::Error

Terminal probe timed out after {}ms

Error message

Terminal probe timed out after {}ms

What it means

enable_raw_mode did not answer within terminal_probe_timeout (default 500 ms; config tui.terminal_probe_timeout_ms clamped to 100-5000 ms), so startup aborts. A SeqCst handshake between the timeout side and the blocking task ensures a late raw-mode enable is always undone, so the terminal is not left raw. A tracing::warn line names the timeout and 'terminal may be unresponsive'.

Source

Thrown at crates/tui/src/tui/ui/event_loop.rs:197

        }
        result
    });

    match tokio::time::timeout(probe_timeout, enable_raw).await {
        Ok(inner_result) => {
            inner_result??; // propagate both join and raw-mode errors
        }
        Err(_) => {
            if raw_mode_probe_handshake(&probe_abandoned, &probe_enabled) {
                // The blocking task finished enabling raw mode right as the
                // timeout fired and may have missed the abandoned flag.
                let _ = disable_raw_mode();
            }
            tracing::warn!(
                "Terminal probe timed out after {}ms - terminal may be unresponsive",
                probe_timeout.as_millis()
            );
            return Err(anyhow::anyhow!(
                "Terminal probe timed out after {}ms",
                probe_timeout.as_millis()
            ));
        }
    }

    #[cfg(target_os = "windows")]
    enable_windows_ime_console_mode();

    let mut stdout = io::stdout();
    // Initialize the file-backed TUI log and redirect raw stderr away from
    // the alt-screen for the lifetime of this guard. MUST run BEFORE
    // EnterAlternateScreen; otherwise logging between alt-screen entry and
    // redirect init leaks raw bytes into the TUI buffer, causing the "scroll
    // demon" on Windows (#1909) and garbled output on all platforms (#1085).
    // The guard is held until the function returns; dropping it after
    // LeaveAlternateScreen restores the original stderr handle/fd so shutdown
    // messages reach the user's terminal. We accept the init failing (e.g.,

View on GitHub (pinned to 0c42157ee5)

Solutions

  1. Reconnect SSH / restart the terminal or multiplexer session, then relaunch
  2. If the terminal is legitimately slow (cold VM), raise tui.terminal_probe_timeout_ms in config (clamped max 5000)
  3. Ensure the launch environment is a healthy PTY - no hung parent, no double attach
  4. Check the warn log line to confirm which timeout fired

Example fix

# config: raise the probe budget on slow terminals
# before: default 500ms
tui:
  terminal_probe_timeout_ms: 2000
Defensive patterns

Strategy: retry

Validate before calling

// Rust - cheap terminal responsiveness preflight before full startup
use std::io::IsTerminal;
fn terminal_likely_responsive() -> bool {
    std::io::stdin().is_terminal() && std::io::stdout().is_terminal()
}

Try / catch

// on probe timeout: do not loop inside the same session - repair the terminal first
match tokio::time::timeout(probe_timeout, enable_raw_probe()).await {
    Err(_) => { let _ = disable_raw_mode(); advise_reconnect_or_raise_probe_timeout(); Err(anyhow::anyhow!("Terminal probe timed out")) }
    Ok(r) => r,
}

Prevention

When it happens

Trigger: A terminal ioctl that blocks past the probe budget: a frozen SSH connection whose PTY no longer answers, a stalled Windows console driver, a wedged tmux/screen session, or extremely slow container/VM cold-start I/O exceeding the configured timeout.

Common situations: Resuming a dropped SSH session; multiplexer in a bad state; CI/service contexts; underpowered VMs on first start where even termios calls are slow.

Understand the failure class

Related errors


AI-assisted analysis of Hmbown/CodeWhale@0c42157ee5 (2026-08-20). Data as JSON: /api/errors/f42d41c9eca70ec1. Report an issue: GitHub.