denisidoro/navi · error
Not enough data
Error message
Not enough data
What it means
This panic comes from an `.expect("Not enough data")` on an iterator item in `width_with_shell_out` (src/common/terminal.rs:31). The function shells out to `stty size`, which prints '<rows> <cols>' on stdout; the code skips the first whitespace-separated token and expects a second token (the column count). If `stty` exits 0 but prints fewer than two tokens (or nothing), the iterator is exhausted and the expect panics. It is a hard panic, not a Result error, though the caller `width()` would have fallen back to 80 columns if it were propagated as an Err.
Source
Thrown at src/common/terminal.rs:31
.arg("size")
.stderr(Stdio::inherit())
.output()?
} else {
Command::new("stty")
.arg("size")
.arg("-F")
.arg("/dev/stderr")
.stderr(Stdio::inherit())
.output()?
};
if let Some(0) = output.status.code() {
let stdout = String::from_utf8(output.stdout).expect("Invalid utf8 output from stty");
let mut data = stdout.split_whitespace();
data.next();
return data
.next()
.expect("Not enough data")
.parse::<u16>()
.map_err(|_| anyhow!("Invalid width"));
}
Err(anyhow!("Invalid status code"))
}
pub fn width() -> u16 {
if let Ok((w, _)) = terminal::size() {
w
} else {
width_with_shell_out().unwrap_or(FALLBACK_WIDTH)
}
}
#[cfg(test)]
mod tests {
use super::*;View on GitHub (pinned to f7330b9ad5)
Solutions
- Ensure the process runs with a real TTY on stderr (allocate a PTY, e.g. `ssh -t`, `script -qec`, or a Docker `-t` flag) so both crossterm and stty can report a size
- Verify `stty -F /dev/stderr size` (or `stty -f /dev/stderr size` on macOS) prints two numbers in your environment; fix or remove broken stty shims from PATH
- Upgrade the library / patch `width_with_shell_out` to check `data.next()` and return `Err(anyhow!("Not enough data"))` instead of panicking, so the existing FALLBACK_WIDTH=80 path applies
- As a workaround, force a known terminal size in CI (e.g. `stty cols 80 rows 24` or `COLUMNS=80`) before invoking
Example fix
// before
return data
.next()
.expect("Not enough data")
.parse::<u16>()
.map_err(|_| anyhow!("Invalid width"));
// after
return data
.next()
.ok_or_else(|| anyhow!("Not enough data"))?
.parse::<u16>()
.map_err(|_| anyhow!("Invalid width")); Defensive patterns
Strategy: fallback
Validate before calling
// Run before relying on the shell-out path:
use std::process::Command;
fn stty_output_ok() -> bool {
let out = Command::new("stty").arg("size").arg("-F").arg("/dev/stderr")
.output().ok();
match out {
Some(o) if o.status.code() == Some(0) => {
let s = String::from_utf8_lossy(&o.stdout);
s.split_whitespace().count() >= 2
&& s.split_whitespace().nth(1).unwrap().parse::<u16>().is_ok()
}
_ => false,
}
} Type guard
fn valid_stty_size(stdout: &str) -> Option<u16> {
let mut it = stdout.split_whitespace();
it.next()?; // rows
it.next()?.parse::<u16>().ok() // columns
} Try / catch
// In Rust, prefer not panicking: change the expect to Result and rely on
// width()'s existing fallback (this library already falls back to 80):
match std::panic::catch_unwind(width_with_shell_out) {
Ok(w) => w,
Err(_) => 80, // FALLBACK_WIDTH
} Prevention
- Always run the tool with a real TTY on stderr; in CI allocate a PTY (docker -t, ssh -t, script -qec)
- Sanity-check `stty -F /dev/stderr size` output in new environments (containers, SSH, multiplexers) before deploying
- Remove or fix stty shims/wrappers from PATH that exit 0 without printing '<rows> <cols>'
- Prefer the library's own fallback: assume width 80 is used when no TTY exists rather than forcing the shell-out path
When it happens
Trigger: `stty` is executed with exit code 0 but its stdout does not contain two whitespace-separated fields — e.g. stdout is empty, or contains only a row count — while the crossterm `terminal::size()` path has already failed (no real TTY). This can happen with unusual/patched stty builds, locale wrappers that emit extra warnings (only if they consume stdout), stubbed stty binaries in CI containers, or pseudo-terminal setups where stty reports success but no size.
Common situations: Running inside Docker/CI where stderr is redirected to a non-tty and an stty shim returns 0 with empty output; environments with a fake or busybox `stty` that behaves differently from GNU/coreutils stty; terminal multiplexers or wrappers that break crossterm's ioctl and then also break the stty fallback; SSH sessions with a broken PTY allocation.
Related errors
AI-assisted analysis of denisidoro/navi@f7330b9ad5 (2026-09-03).
Data as JSON: /api/errors/286bf161c3820d60.
Report an issue: GitHub.