charmbracelet / charmbracelet/bubbletea

v2: no way to sync tea.Println/insertAbove with the frame flush (stale frame row welded into scrollback)

Open
#1,736 1 comment 0 reactions 0 assignees View on GitHub
Dominant language
Go
Stars
44.9k
Forks
1.3k
PR merge metrics
No merged PRs in 30d

Description

**Describe the bug**

There's no way to synchronize `tea.Println` / `insertAbove` with the frame flush. `insertAbove` runs synchronously in the event loop and scrolls using the **last-flushed** frame (`cellbuf` / `scr.Position()`), while `View()` is only stored by `render()` and flushed **asynchronously on the FPS ticker**. So in an inline (non-alt-screen) app that commits to scrollback via `tea.Println` while the live `View()` changes height, a stale live-frame row can get welded into scrollback (e.g. a table's top border duplicated above the correct block). There's no flush-ack to gate on either — `p.Send` is async and `tea.Sequence` only orders enqueue.

**Setup:** v2.0.8 (same on `main`), inline mode.

**Question:** would you accept flushing `s.view` before `insertAbove` in the `printLineMessage` handler — or is there a supported way to sync a `Println` with a completed flush?

Real-world symptom + downstream context: genai-io/san#314. Related: #1666, #1613 / #1678.

Contributor guide

Open the contributing guide

Research direction

Start by tracing the printLineMessage handler, insertAbove, render(), and the asynchronous frame flush, including the cellbuf/scr.Position() state described in the report. Reproduce the issue in inline mode with a changing-height View() and tea.Println, then determine what synchronization contract prevents a stale frame row from entering scrollback.

Written by the indexing model from the issue text.

Assessment

Tech stack
go
Domain
cli
Issue type
Bug
Difficulty
5/5
Estimated time
Over a week
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.