{"record":{"id":"f42d41c9eca70ec1","repo":"Hmbown/CodeWhale","slug":"terminal-probe-timed-out-after-ms","errorCode":null,"errorMessage":"Terminal probe timed out after {}ms","messagePattern":"Terminal probe timed out after (.+?)ms","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/tui/src/tui/ui/event_loop.rs","lineNumber":197,"sourceCode":"        }\n        result\n    });\n\n    match tokio::time::timeout(probe_timeout, enable_raw).await {\n        Ok(inner_result) => {\n            inner_result??; // propagate both join and raw-mode errors\n        }\n        Err(_) => {\n            if raw_mode_probe_handshake(&probe_abandoned, &probe_enabled) {\n                // The blocking task finished enabling raw mode right as the\n                // timeout fired and may have missed the abandoned flag.\n                let _ = disable_raw_mode();\n            }\n            tracing::warn!(\n                \"Terminal probe timed out after {}ms - terminal may be unresponsive\",\n                probe_timeout.as_millis()\n            );\n            return Err(anyhow::anyhow!(\n                \"Terminal probe timed out after {}ms\",\n                probe_timeout.as_millis()\n            ));\n        }\n    }\n\n    #[cfg(target_os = \"windows\")]\n    enable_windows_ime_console_mode();\n\n    let mut stdout = io::stdout();\n    // Initialize the file-backed TUI log and redirect raw stderr away from\n    // the alt-screen for the lifetime of this guard. MUST run BEFORE\n    // EnterAlternateScreen; otherwise logging between alt-screen entry and\n    // redirect init leaks raw bytes into the TUI buffer, causing the \"scroll\n    // demon\" on Windows (#1909) and garbled output on all platforms (#1085).\n    // The guard is held until the function returns; dropping it after\n    // LeaveAlternateScreen restores the original stderr handle/fd so shutdown\n    // messages reach the user's terminal. We accept the init failing (e.g.,","sourceCodeStart":179,"sourceCodeEnd":215,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/0c42157ee52f9d55af2b506d71b46249910f77d3/crates/tui/src/tui/ui/event_loop.rs#L179-L215","documentation":"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'.","triggerScenarios":"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.","commonSituations":"Resuming a dropped SSH session; multiplexer in a bad state; CI/service contexts; underpowered VMs on first start where even termios calls are slow.","solutions":["Reconnect SSH / restart the terminal or multiplexer session, then relaunch","If the terminal is legitimately slow (cold VM), raise tui.terminal_probe_timeout_ms in config (clamped max 5000)","Ensure the launch environment is a healthy PTY - no hung parent, no double attach","Check the warn log line to confirm which timeout fired"],"exampleFix":"# config: raise the probe budget on slow terminals\n# before: default 500ms\ntui:\n  terminal_probe_timeout_ms: 2000","handlingStrategy":"retry","validationCode":"// Rust - cheap terminal responsiveness preflight before full startup\nuse std::io::IsTerminal;\nfn terminal_likely_responsive() -> bool {\n    std::io::stdin().is_terminal() && std::io::stdout().is_terminal()\n}","typeGuard":null,"tryCatchPattern":"// on probe timeout: do not loop inside the same session - repair the terminal first\nmatch tokio::time::timeout(probe_timeout, enable_raw_probe()).await {\n    Err(_) => { let _ = disable_raw_mode(); advise_reconnect_or_raise_probe_timeout(); Err(anyhow::anyhow!(\"Terminal probe timed out\")) }\n    Ok(r) => r,\n}","preventionTips":["Reconnect dropped SSH sessions before resuming the TUI","Raise tui.terminal_probe_timeout_ms (max 5000) only for genuinely slow terminals, not to mask a wedged PTY","Restart wedged tmux/screen sessions instead of retrying into them"],"tags":["terminal","timeout","raw-mode","probe","startup"],"backgroundTag":"terminal-unresponsive-timeout","analyzedSha":"0c42157ee52f9d55af2b506d71b46249910f77d3","analyzedAt":"2026-08-20T21:50:45.477Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}