xai-org/grok-build · warning · io::Error

Invalid viewport height: {} (terminal height: {})

Error message

Invalid viewport height: {} (terminal height: {})

What it means

resize_viewport_height validates the requested viewport height: it must be nonzero and strictly less than the current terminal height. Out-of-range requests are rejected with io::ErrorKind::InvalidInput so the inline viewport never consumes the whole terminal or collapses to nothing.

Source

Thrown at crates/codegen/xai-ratatui-inline/src/resize.rs:123

) -> io::Result<()> {
    macro_rules! queue {
        ($($command:expr),* $(,)?) => {{
            $(crossterm::queue!(terminal.writer_mut(), $command)?;)*
            Ok::<(), io::Error>(())
        }};
    }

    let size = terminal.size()?;
    let current_viewport = terminal.viewport_area();
    let old_height = current_viewport.height;

    if new_height == old_height {
        return Ok(());
    }

    // Ensure new height is valid
    if new_height == 0 || new_height >= size.height {
        return Err(io::Error::new(
            io::ErrorKind::InvalidInput,
            format!(
                "Invalid viewport height: {} (terminal height: {})",
                new_height, size.height
            ),
        ));
    }

    if new_height > old_height {
        // Growing: Smart expansion - try to expand down first, then push content up if needed
        let growth = new_height - old_height;
        let bottom_edge = current_viewport.y + current_viewport.height;
        let space_below = size.height.saturating_sub(bottom_edge);

        // Calculate the new y position
        let new_y = if space_below >= growth {
            // We have enough space below - expand down, keep same y
            current_viewport.y

View on GitHub (pinned to bc7f02eddd)

Solutions

  1. Clamp the requested height to 1..terminal_height before calling: let h = h.max(1).min(term_height - 1).max(1);
  2. Re-query terminal size at resize time instead of using a cached value
  3. Skip the resize (no-op) when the clamped height equals the current height

Example fix

// before
resize_viewport_height(new_height)?;
// after
let size = terminal::size()?;
let clamped = new_height.clamp(1, size.height.saturating_sub(1));
if clamped != new_height { /* log/adjust */ }
resize_viewport_height(clamped)?;
Defensive patterns

Strategy: validation

Validate before calling

fn valid_viewport_height(h: u16, term_height: u16) -> bool {
    h > 0 && h < term_height
}
let size = crossterm::terminal::size()?;
let new_height = new_height.clamp(1, size.height.saturating_sub(1).max(1));

Type guard

fn valid_viewport_height(h: u16, term_height: u16) -> bool {
    h > 0 && h < term_height
}

Try / catch

if let Err(e) = resize_viewport_height(new_height) {
    if e.kind() == io::ErrorKind::InvalidInput {
        let size = crossterm::terminal::size()?;
        resize_viewport_height(new_height.clamp(1, size.height.saturating_sub(1)))?;
    } else { return Err(e.into()); }
}

Prevention

When it happens

Trigger: Calling resize_viewport_height(0), or with a height >= the terminal's current row count (queried via terminal size), including when the terminal shrank between calls and a stale cached height is now too large.

Common situations: Handling a terminal-resize event with a stale cached terminal height; clamping math producing 0; running in a tiny/unset terminal (height 1) where any nonzero viewport is invalid; test harnesses with a mocked size.

Related errors


AI-assisted analysis of xai-org/grok-build@bc7f02eddd (2026-08-31). Data as JSON: /api/errors/4ce1278427e0aac4. Report an issue: GitHub.