[BUG] Newer emoji U+1FAEA ( "DISTORTED FACE", Unicode 17.0) corrupts TUI render — cell-width mismatch, column misalignment & stray-glyph artifacts
Summary
Typing/pasting the emoji (U+1FAEA "DISTORTED FACE") into Claude Code corrupts the TUI render. The glyph occupies a different number of terminal cells than Claude Code's internal string-width calculation assumes, so every character after it on the reflowed line is shifted by a cell. The result is stray glyphs, inverse-video block artifacts between words, and broken column alignment. It affects both the FleetView job panel and the main session transcript — any line that contains the emoji.
Environment
| | |
|---|---|
| Claude Code version | 2.1.207 |
| OS | macOS 27.0 (build 26A5353q) |
| Shell | zsh |
| Terminal env | TERM=xterm-256color, COLORTERM=truecolor, LANG=en_US.UTF-8 |
Steps to reproduce
- Start Claude Code in a terminal.
- In the prompt input, type or paste the emoji (U+1FAEA, UTF-8
f0 9f ab aa). - Observe the input line, and after sending, the rendered transcript / FleetView panel.
Expected
The emoji renders as a single wide glyph and all surrounding text stays column-aligned.
Actual
- Column alignment breaks starting at the emoji; text after it is shifted by one cell.
- Stray characters leak into adjacent UI rows (e.g. a stray
d+ cursor block bleeding into a neighboring FleetView row). - In the transcript, reflowed paragraphs show inverse-video block artifacts inserted between words.
- The corruption redraws incorrectly and persists on that line until a full repaint (
Ctrl-L/ window resize).
Root cause (analysis)
Classic character-width (wcwidth) mismatch on a newly-assigned codepoint:
- U+1FAEA "DISTORTED FACE" was added in Unicode 17.0 (Sept 2025) — very recent.
- Older Unicode data tables classify U+1FAEA as unassigned (
Cn) with East Asian WidthN(narrow → 1 cell). Verified locally: Pythonunicodedatav15.0.0 reportscategory=Cn,east_asian_width=Nfor this codepoint. - Up-to-date terminals + emoji fonts render it with Emoji_Presentation = 2 cells (wide).
- Claude Code's string-width logic appears to rely on a width table predating Unicode 17.0, so it counts the emoji as 1 (or 0) cells while the terminal draws 2. The off-by-N cell delta desyncs Claude Code's internal cursor/column model from the physical terminal and corrupts the rest of the line (and anything laid out relative to it).
This will reproduce for any codepoint newer than Claude Code's bundled width table, not just U+1FAEA — other recent Unicode 16.0/17.0 emoji are likely affected too.
Impact / severity
- Severity: medium — cosmetic, no data loss, but disruptive: corrupts the live TUI, can smear across FleetView rows, and makes the session hard to read until a repaint.
- Frequency: deterministic — every time the character is present in a rendered line.
Suggested fix
- Update the bundled character-width /
wcwidthtable to Unicode 17.0 (or newer), ensuringEmoji_Presentationcodepoints are measured as width 2. - More robustly: treat codepoints that are unassigned-in-table but fall in
Extended_Pictographic/ high-plane emoji ranges as width 2 by default, so future-newer emoji degrade gracefully instead of desyncing the renderer. - Consider width-clamping/sanitizing at the render boundary so a single mis-measured glyph can't corrupt neighboring UI regions (defense in depth against this class of bug).
Workaround
Avoid pasting brand-new (Unicode 16.0/17.0-era) emoji into the prompt. If a line gets corrupted, force a full repaint with Ctrl-L or by resizing the window.
Notes
Screenshots reproducing the corruption in both FleetView and the transcript are available; happy to attach on request.
3 Comments
<img width="2275" height="470" alt="Image" src="https://github.com/user-attachments/assets/3cca4963-da1b-42fc-8599-ab8277289058" />
I typed (U+1FAE9, Face with Bags Under Eyes) into Claude today and had the same problem.
Thanks for the detailed report. I was able to reproduce this on 2.1.207 (and every release through 2.1.220): typing (U+1FAEA) or (U+1FAE9) into the prompt advanced the cursor by only one cell and the glyph before it got overdrawn, exactly as described.
On 2.1.221 and later (verified on 2.1.221, 2.1.222, 2.1.227 and the current 2.1.233) both emoji are measured as two cells, the cursor lands in the right column, and the input line and transcript render cleanly. The fix came from updating the Unicode width tables in the runtime Claude Code ships with, so newer emoji from Unicode 16/17 are now measured correctly.
See the changelog: https://github.com/anthropics/claude-code/blob/main/CHANGELOG.md. Please update to the latest version (
claude update). Closing as fixed — reply here if you still see it on 2.1.221+ and we'll reopen.🤖 Generated with Claude Code