charmbracelet/bubbletea · error
bubbletea: error getting terminal size: %w
Error message
bubbletea: error getting terminal size: %w
What it means
Returned by Program.Run right after terminal init when term.GetSize on the output TTY file descriptor fails, so Bubble Tea cannot learn the initial terminal dimensions to size the first frame. The wrapped error is typically an ioctl (TIOCGWINSZ) failure such as EINVAL or ENOTTY. Program startup aborts and the terminal state is restored.
Source
Thrown at tea.go:1047
returnErr = fmt.Errorf("%w: %w", ErrProgramKilled, ErrProgramPanic)
p.recoverFromPanic(r)
}
}()
}
// Check if output is a TTY before entering raw mode, hiding the cursor and
// so on.
if err := p.initTerminal(); err != nil {
return p.initialModel, err
}
// Get the initial window size.
width, height := p.width, p.height
if p.ttyOutput != nil {
// Set the initial size of the terminal.
w, h, err := term.GetSize(p.ttyOutput.Fd())
if err != nil {
return p.initialModel, fmt.Errorf("bubbletea: error getting terminal size: %w", err)
}
width, height = w, h
}
p.width, p.height = width, height
resizeMsg := WindowSizeMsg{Width: p.width, Height: p.height}
if p.renderer == nil {
if p.disableRenderer {
p.renderer = &nilRenderer{}
} else {
// If no renderer is set use the cursed one.
r := newCursedRenderer(
p.output,
p.environ,
p.width,
p.height,View on GitHub (pinned to 351d2159f8)
Solutions
- If output is not a real terminal, pass tea.WithOutput(io.Discard) or os.Stdout with tea.WithoutRenderer()
- Set an explicit initial size with tea.WithWindowSize? no — instead pre-set via Program options like tea.WithAltScreen is unrelated: use p's width/height by constructing with tea.WithInput... ultimately: avoid fake TTYs; run inside a real terminal or real pty (e.g. creack/pty in tests)
- Retry starting the program after a short delay if the terminal was mid-initialization
- Check the wrapped errno: ENOTTY means non-terminal output — switch to non-renderer mode
Example fix
// before
p := tea.NewProgram(m, tea.WithOutput(f)) // f: not a real tty, ioctl fails
_, err := p.Run()
// after
if term.IsTerminal(f.Fd()) {
p := tea.NewProgram(m, tea.WithOutput(f))
_, err = p.Run()
} else {
p := tea.NewProgram(m, tea.WithoutRenderer(), tea.WithOutput(f))
_, err = p.Run()
} Defensive patterns
Strategy: validation
Validate before calling
// Validate the output fd supports window-size queries before Run:
func supportsWINSZ(f *os.File) bool {
_, _, err := term.GetSize(f.Fd())
return err == nil
}
if !supportsWINSZ(out) {
p := tea.NewProgram(m, tea.WithoutRenderer(), tea.WithOutput(out))
// ... run in plain mode
} Type guard
func isGetSizeFailure(err error) bool {
return err != nil && strings.Contains(err.Error(), "error getting terminal size")
} Try / catch
_, err := p.Run()
if isGetSizeFailure(err) {
if errors.Is(errors.Unwrap(err), syscall.ENOTTY) {
// fall back to renderer-less mode
_, err = tea.NewProgram(m, tea.WithoutRenderer()).Run()
}
}
if err != nil { log.Fatal(err) } Prevention
- Use a real terminal or a real pty in integration tests
- Don't point tea.WithOutput at files/sockets and expect TUI behavior
- Retry once shortly after login/pty setup races
- Prefer os.Stdout directly in normal CLI usage
When it happens
Trigger: Output is a TTY-like handle that doesn't support the window-size ioctl (some ptys mid-teardown, closed fds, serial consoles); output set via tea.WithOutput to a file/socket that passed TTY checks but fails TIOCGWINSZ; terminal emulator in a transient state during startup; fd limit issues.
Common situations: Running under a half-configured pty in tests; output redirected to /dev/null on some platforms; running inside certain CI pseudo-terminals or `script` wrappers; race between terminal creation and program start; exotic environments (jails, containers) with limited ioctls.
Related errors
- bubbletea: error opening TTY: %w
- bubbletea: error restoring console: %w
- program experienced a panic
- program was killed
- program was interrupted
AI-assisted analysis of charmbracelet/bubbletea@351d2159f8 (2026-08-15).
Data as JSON: /api/errors/ae28b3bf38505664.
Report an issue: GitHub.