wezterm/wezterm · error · anyhow::Error

failed to resize console to {}x{}: HRESULT: {}

Error message

failed to resize console to {}x{}: HRESULT: {}

What it means

On terminal resize, wezterm calls ResizePseudoConsole with the new dimensions; a failing HRESULT is reported together with the requested size. ConPTY commonly rejects degenerate sizes (0 rows/cols) and can transiently fail during rapid resizes or while the conhost side is shutting down.

Source

Thrown at pty/src/win/psuedocon.rs:101

                input.as_raw_handle(),
                output.as_raw_handle(),
                PSUEDOCONSOLE_INHERIT_CURSOR
                    | PSEUDOCONSOLE_RESIZE_QUIRK
                    | PSEUDOCONSOLE_WIN32_INPUT_MODE,
                &mut con,
            )
        };
        ensure!(
            result == S_OK,
            "failed to create psuedo console: HRESULT {}",
            result
        );
        Ok(Self { con })
    }

    pub fn resize(&self, size: COORD) -> Result<(), Error> {
        let result = unsafe { (CONPTY.ResizePseudoConsole)(self.con, size) };
        ensure!(
            result == S_OK,
            "failed to resize console to {}x{}: HRESULT: {}",
            size.X,
            size.Y,
            result
        );
        Ok(())
    }

    pub fn spawn_command(&self, cmd: CommandBuilder) -> anyhow::Result<WinChild> {
        let mut si: STARTUPINFOEXW = unsafe { mem::zeroed() };
        si.StartupInfo.cb = mem::size_of::<STARTUPINFOEXW>() as u32;
        // Explicitly set the stdio handles as invalid handles otherwise
        // we can end up with a weird state where the spawned process can
        // inherit the explicitly redirected output handles from its parent.
        // For example, when daemonizing wezterm-mux-server, the stdio handles
        // are redirected to a log file and the spawned process would end up
        // writing its output there instead of to the pty we just created.

View on GitHub (pinned to 08e5e0afc6)

Solutions

  1. Clamp dimensions to at least 1x1 before calling resize
  2. Treat resize failure as non-fatal: log and keep the last good size
  3. Update Windows and wezterm; ConPTY resize quirks are patched over time
  4. Map the HRESULT from the message against winerror.h to confirm which case it is

Example fix

// before: forward raw sizes
con.resize(size)?;
// after: clamp first
let clamped = COORD { X: size.X.max(1), Y: size.Y.max(1) };
con.resize(clamped)?;
Defensive patterns

Strategy: validation

Validate before calling

// embedders: never forward degenerate dimensions
fn clamp_size(size: COORD) -> COORD {
    COORD { X: size.X.max(1), Y: size.Y.max(1) }
}

Try / catch

// treat resize failures as non-fatal; keep last good size
if let Err(err) = con.resize(clamp_size(size)) {
    log::warn!("conpty resize to {}x{} failed: {err:#}", size.X, size.Y);
}

Prevention

When it happens

Trigger: Resizing to 0x0 or other out-of-range sizes; resizing during pty teardown; rapid successive resizes hitting ConPTY race conditions; conhost crash mid-resize.

Common situations: Dragging window edges back and forth aggressively; panes being closed while a resize event is in flight; embedders forwarding arbitrary dimensions.

Related errors


AI-assisted analysis of wezterm/wezterm@08e5e0afc6 (2026-08-20). Data as JSON: /api/errors/651a4e84867e2c98. Report an issue: GitHub.