[GH-ISSUE #306] Non-scrollable TextView panics with "index out of range" when resizing the terminal #233

Closed
opened 2026-03-04 01:03:11 +03:00 by kerem · 1 comment
Owner

Originally created by @denilsonsa on GitHub (Jun 14, 2019).
Original GitHub issue: https://github.com/rivo/tview/issues/306

I'm getting this error:

panic: runtime error: index out of range [recovered]
	panic: runtime error: index out of range

goroutine 1 [running]:
github.com/rivo/tview.(*Application).Run.func1(0xc4200fe100)
	/home/dsa/go/src/github.com/rivo/tview/application.go:149 +0x82
panic(0x577a60, 0x674930)
	/usr/lib/go-1.10/src/runtime/panic.go:502 +0x229
github.com/rivo/tview.(*TextView).Draw(0xc4200808f0, 0x5c33c0, 0xc420120000)
	/home/dsa/go/src/github.com/rivo/tview/textview.go:942 +0xaac
github.com/rivo/tview.(*Grid).Draw(0xc42011e000, 0x5c33c0, 0xc420120000)
	/home/dsa/go/src/github.com/rivo/tview/grid.go:583 +0x1473
github.com/rivo/tview.(*Application).draw(0xc4200fe100, 0x0)
	/home/dsa/go/src/github.com/rivo/tview/application.go:363 +0xd3
github.com/rivo/tview.(*Application).QueueUpdateDraw.func1()
	/home/dsa/go/src/github.com/rivo/tview/application.go:494 +0x40
github.com/rivo/tview.(*Application).Run(0xc4200fe100, 0x0, 0x0)
	/home/dsa/go/src/github.com/rivo/tview/application.go:253 +0x4cd
main.main()
	/home/dsa/go/src/dsa-slapper/testcase.go:74 +0x503

Seems to be related to this line of code:

t.buffer = t.buffer[t.index[t.lineOffset].Line:]

How to reproduce?

  1. Try the minimal testcase below.
  2. Resize your terminal like crazy.
    • With this minimal testcase, it took several seconds to randomly reproduce the crash. With my real-world code (much larger), I got this error very often while resizing the terminal.

You can see a screen recording of this bug: https://youtu.be/crFWsLL9T5Q

package main

import (
	"fmt"
	"github.com/gdamore/tcell"
	"github.com/rivo/tview"
	"time"
)

var (
	cells  []*tview.TextView
	app    *tview.Application
	ticker *time.Ticker
	quit   chan interface{}
)

func draw() {
	for {
		select {
		case t := <-ticker.C:
			app.QueueUpdateDraw(func() {
				for _, cell := range cells {
					cell.Clear()
					hh, mm, ss := t.Clock()
					fmt.Fprintf(cell, "%02d:%02d:%02d\n", hh, mm, ss)
					fmt.Fprintf(cell, "Lorem Ipsum [w][s]\n")
					fmt.Fprintf(cell, "Lorem Ipsum\n")
					fmt.Fprintf(cell, "Lorem Ipsums [r][f]\n")
					fmt.Fprintf(cell, "\n")
					fmt.Fprintf(cell, "[q] to quit\n")
				}
			})
		case <-quit:
			return
		}
	}
}

func buildTextView() *tview.TextView {
	return tview.NewTextView().SetDynamicColors(false).SetScrollable(false).SetWrap(false).SetTextAlign(tview.AlignLeft)
}

func main() {
	quit = make(chan interface{})
	grid := tview.NewGrid().SetBorders(true)

	cells = []*tview.TextView{
		buildTextView(),
		buildTextView(),
		buildTextView(),
	}

	for i, cell := range cells {
		grid.AddItem(cell, i, 0, 1, 1, 0, 0, false)
	}

	app = tview.NewApplication().SetRoot(grid, true)

	app.SetInputCapture(func(ev *tcell.EventKey) *tcell.EventKey {
		switch ev.Key() {
		case tcell.KeyCtrlC:
			app.Stop()
		case tcell.KeyRune:
			switch ev.Rune() {
			case 'q':
				app.Stop()
			}
		}
		return nil
	})

	ticker = time.NewTicker(100 * time.Millisecond)
	go draw()
	if err := app.Run(); err != nil {
		panic(err)
	}
	ticker.Stop()
	close(quit)
}
Originally created by @denilsonsa on GitHub (Jun 14, 2019). Original GitHub issue: https://github.com/rivo/tview/issues/306 I'm getting this error: ``` panic: runtime error: index out of range [recovered] panic: runtime error: index out of range goroutine 1 [running]: github.com/rivo/tview.(*Application).Run.func1(0xc4200fe100) /home/dsa/go/src/github.com/rivo/tview/application.go:149 +0x82 panic(0x577a60, 0x674930) /usr/lib/go-1.10/src/runtime/panic.go:502 +0x229 github.com/rivo/tview.(*TextView).Draw(0xc4200808f0, 0x5c33c0, 0xc420120000) /home/dsa/go/src/github.com/rivo/tview/textview.go:942 +0xaac github.com/rivo/tview.(*Grid).Draw(0xc42011e000, 0x5c33c0, 0xc420120000) /home/dsa/go/src/github.com/rivo/tview/grid.go:583 +0x1473 github.com/rivo/tview.(*Application).draw(0xc4200fe100, 0x0) /home/dsa/go/src/github.com/rivo/tview/application.go:363 +0xd3 github.com/rivo/tview.(*Application).QueueUpdateDraw.func1() /home/dsa/go/src/github.com/rivo/tview/application.go:494 +0x40 github.com/rivo/tview.(*Application).Run(0xc4200fe100, 0x0, 0x0) /home/dsa/go/src/github.com/rivo/tview/application.go:253 +0x4cd main.main() /home/dsa/go/src/dsa-slapper/testcase.go:74 +0x503 ``` Seems to be related to this line of code: t.buffer = t.buffer[t.index[t.lineOffset].Line:] How to reproduce? 1. Try the minimal testcase below. 2. Resize your terminal like crazy. * With this minimal testcase, it took several seconds to randomly reproduce the crash. With my real-world code (much larger), I got this error very often while resizing the terminal. You can see a screen recording of this bug: https://youtu.be/crFWsLL9T5Q ```go package main import ( "fmt" "github.com/gdamore/tcell" "github.com/rivo/tview" "time" ) var ( cells []*tview.TextView app *tview.Application ticker *time.Ticker quit chan interface{} ) func draw() { for { select { case t := <-ticker.C: app.QueueUpdateDraw(func() { for _, cell := range cells { cell.Clear() hh, mm, ss := t.Clock() fmt.Fprintf(cell, "%02d:%02d:%02d\n", hh, mm, ss) fmt.Fprintf(cell, "Lorem Ipsum [w][s]\n") fmt.Fprintf(cell, "Lorem Ipsum\n") fmt.Fprintf(cell, "Lorem Ipsums [r][f]\n") fmt.Fprintf(cell, "\n") fmt.Fprintf(cell, "[q] to quit\n") } }) case <-quit: return } } } func buildTextView() *tview.TextView { return tview.NewTextView().SetDynamicColors(false).SetScrollable(false).SetWrap(false).SetTextAlign(tview.AlignLeft) } func main() { quit = make(chan interface{}) grid := tview.NewGrid().SetBorders(true) cells = []*tview.TextView{ buildTextView(), buildTextView(), buildTextView(), } for i, cell := range cells { grid.AddItem(cell, i, 0, 1, 1, 0, 0, false) } app = tview.NewApplication().SetRoot(grid, true) app.SetInputCapture(func(ev *tcell.EventKey) *tcell.EventKey { switch ev.Key() { case tcell.KeyCtrlC: app.Stop() case tcell.KeyRune: switch ev.Rune() { case 'q': app.Stop() } } return nil }) ticker = time.NewTicker(100 * time.Millisecond) go draw() if err := app.Run(); err != nil { panic(err) } ticker.Stop() close(quit) } ```
kerem closed this issue 2026-03-04 01:03:12 +03:00
Author
Owner

@rivo commented on GitHub (Jul 9, 2019):

Thanks. The latest commit should fix this.

<!-- gh-comment-id:509634444 --> @rivo commented on GitHub (Jul 9, 2019): Thanks. The latest commit should fix this.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/tview#233
No description provided.