-
Notifications
You must be signed in to change notification settings - Fork 356
Open
Description
Description
The viewport panics with slice bounds out of range when the Height is set to a negative or zero value. This commonly occurs when resizing the terminal window to be very small while using a viewport alongside other components (e.g., textarea).
Stack Trace
runtime error: slice bounds out of range [8:4]
goroutine 1 [running]:
github.com/charmbracelet/bubbles/viewport.Model.visibleLines(...)
viewport/viewport.go:150
github.com/charmbracelet/bubbles/viewport.(*Model).GotoBottom(...)
viewport/viewport.go:348
Root Cause
In visibleLines() (viewport.go:143-150), when Height becomes negative:
func (m Model) visibleLines() (lines []string) {
h := m.Height - m.Style.GetVerticalFrameSize() // h can be negative
// ...
if len(m.lines) > 0 {
top := max(0, m.YOffset)
bottom := clamp(m.YOffset+h, top, len(m.lines)) // bottom can be < top
lines = m.lines[top:bottom] // PANIC: invalid slice bounds
}
}When h is negative and YOffset is positive (from a previous scroll), bottom becomes less than top, causing the panic.
Steps to Reproduce
- Create a viewport with another component that takes up vertical space
- Calculate viewport height as:
msg.Height - otherComponent.Height() - gap - Shrink the terminal window until the calculated height becomes negative
- The viewport panics
Minimal Example
case tea.WindowSizeMsg:
m.viewport.Height = msg.Height - m.textarea.Height() - 2 // Can go negative
m.viewport.GotoBottom() // Triggers panicSuggested Fix
Add a guard in visibleLines() to handle the case where top >= bottom:
if len(m.lines) > 0 {
top := max(0, m.YOffset)
bottom := clamp(m.YOffset+h, top, len(m.lines))
if top >= bottom {
return nil
}
lines = m.lines[top:bottom]
}Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels