Hmbown/CodeWhale · error

terminal host window no longer exists

Error message

terminal host window no longer exists

What it means

WindowControl::capture looks up the console host window (console_hwnd) and then reads its owning process id via GetWindowThreadProcessId. If the owner pid comes back 0, the window handle is stale or the window has been destroyed, so capture bails with this error rather than caching a dead handle.

Solutions

  1. Re-capture the host window (call capture again) so a fresh console_hwnd is resolved.
  2. Verify the terminal hosting the TUI is still open and attached to a console.
  3. On non-Windows or headless environments, skip pinning/window-control entirely (this code is Windows-only).
Defensive patterns

Strategy: validation

Validate before calling

// Windows-only: confirm a live console host before capture
let hwnd = console_hwnd();
let mut pid = 0u32;
if hwnd.is_ok() {
    unsafe { GetWindowThreadProcessId(hwnd.unwrap(), Some(&mut pid)); }
}
let capturable = pid != 0;

Try / catch

match WindowControl::capture() {
    Err(e) if e.to_string().contains("no longer exists") => skip_pinning_and_log(),
    other => other?,
}

Prevention

When it happens

Trigger: Calling capture on Windows when the console window's owning process has exited, so GetWindowThreadProcessId returns 0 for the hwnd obtained from console_hwnd().

Common situations: The terminal was closed or detached between obtaining the console window and capture; running under an environment with no real console host; conhost/Windows Terminal restart replaced the host process mid-session.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22). Data as JSON: /api/errors/938b53f2e7a229c5. Report an issue: GitHub.

Appendix: source

Thrown at crates/tui/src/tui/window_control.rs:107

            BUSY.store(false, Ordering::Release);
        }
    }

    #[derive(Clone, Copy)]
    struct HostWindow {
        handle: isize,
        owner_pid: u32,
    }

    impl HostWindow {
        fn capture() -> Result<Self> {
            let hwnd = console_hwnd().context("no terminal host window found")?;
            let mut owner_pid = 0;
            unsafe {
                GetWindowThreadProcessId(hwnd, Some(&mut owner_pid));
            }
            if owner_pid == 0 {
                bail!("terminal host window no longer exists");
            }
            Ok(Self {
                handle: hwnd.0 as isize,
                owner_pid,
            })
        }

        fn hwnd(self) -> Result<HWND> {
            let hwnd = HWND(self.handle as *mut _);
            let mut owner_pid = 0;
            unsafe {
                GetWindowThreadProcessId(hwnd, Some(&mut owner_pid));
            }
            if owner_pid != self.owner_pid {
                bail!("terminal host window owner changed");
            }
            Ok(hwnd)
        }

View on GitHub (pinned to 73e0f67d83)