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.yView on GitHub (pinned to bc7f02eddd)
Solutions
- Clamp the requested height to 1..terminal_height before calling: let h = h.max(1).min(term_height - 1).max(1);
- Re-query terminal size at resize time instead of using a cached value
- 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
- Re-query terminal size on every resize event instead of caching it
- Clamp user/config-supplied heights into 1..(term_height - 1)
- Handle tiny terminals (height <= 2) by skipping or minimizing the viewport
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
- exactly one of worktreePath or idOrPath must be set, not bot
- either worktreePath or idOrPath must be set
- terminal writer stopped
- invalid deny glob {glob:?}: {e}
- hook JSON alias validation failed: {e}
AI-assisted analysis of xai-org/grok-build@bc7f02eddd (2026-08-31).
Data as JSON: /api/errors/4ce1278427e0aac4.
Report an issue: GitHub.