Baike.dev
All toolsAI codingTrendingOpen sourceNewsSubmit
Log in
Back to tool/Back to issues
#1802·bubbletea

`tea.Println` can add an extra line for a wide grapheme in the WcWidth fallback

Author: N0zoM1z0Created Sep 12, 2026Updated Sep 12, 2026

Describe the bug

When the terminal does not answer Bubble Tea's Unicode-core mode query, the renderer keeps the WcWidth screen-buffer method. The tea.Println path then counts the inserted text with ansi.StringWidth, which uses grapheme-width semantics. The two calculations disagree for some emoji sequences.

With an eight-column buffer, ️‍aaaaaaa fits according to the active WcWidth buffer, but insertAbove counts it as wider than the buffer. The renderer therefore emits one additional newline for the same visual input that the ASCII control occupies in one line. In a real application this leaves a blank row or shifts the managed view after tea.Println output is inserted.

Setup

  • OS see attachments/environment.txt
  • Shell see attachments/environment.txt
  • Terminal Emulator eight-column PTY; see attachments/environment.txt
  • Terminal Multiplexer [none]

The source under test is Bubble Tea v2 at audited revision 73b6d91ac1c3854dd4af046ab5f9e51d3b3b4290.

To Reproduce

From this report directory, run:

bash attachments/repro.sh

The script builds a small Bubble Tea v2 program and runs it in an eight-column PTY. It deliberately does not answer CSI ?2027$p, then compares an ASCII control with ️‍aaaaaaa. Three consecutive runs produced the same result:

PASS case=ascii default-wc insertion newlines=1
FAIL unicode grapheme changed Wc insertion offset: expected=1 actual=2
checked=2 failures=1

The complete captured traces and run hashes are in attachments/evidence.log. The terminal-query setup is recorded in attachments/environment.txt.

Source Code

The audited revision is 73b6d91ac1c3854dd4af046ab5f9e51d3b3b4290, the public Bubble Tea main revision checked for this report on 2026-09-12.

Program.Println queues a printLineMessage in tea.go. The normal startup path creates a cursedRenderer and asks the terminal for Unicode-core mode (2027) in tea.go and tea.go. If the terminal does not report that mode, the screen buffer remains on its default WcWidth method. The method switch itself is visible in cursed_renderer.go.

The mismatch is in insertAbove: it obtains the active buffer dimensions at lines 765–767, splits the queued text into logical lines, and then computes the extra wrapped-line count with ansi.StringWidth at lines 776–783. The subsequent newline insertion uses that count at line 786:

cursed_renderer.go

The renderer consequently mixes the active buffer's width policy with a separate grapheme-width measurement. A terminal that successfully enables Unicode-core mode does not exercise this fallback, which is why the missing terminal response is part of the reproducer rather than an incidental detail.

Expected behavior

The line-count calculation should use the width method of the active screen buffer. In the fallback case, the Unicode input above should produce the same single inserted line as the eight-column ASCII control, rather than adding an extra blank row.

Screenshots

No screenshots were captured.

Additional context

I searched the existing Bubble Tea issues and did not find a report for this tea.Println/insertAbove width-policy mismatch. Issues #1736, #1740, #1741, and #1742 concern flushing, first-flush cursor movement, or related renderer sequencing. They do not cover a stable extra newline caused by a wide grapheme in the WcWidth fallback.

The report artifacts are:

  • repro.sh
  • evidence.log
  • environment.txt
  • attachments.zip

attachments.zip

Source: charmbracelet/bubbletea

View original on GitHubView discussion on GitHub