Permission-mode indicators use U+23F5 (⏵), a codepoint no common monospace font ships — replace with U+25B6 (▶)
Summary
The permission-mode indicators use U+23F5 BLACK MEDIUM RIGHT-POINTING TRIANGLE (⏵⏵), which renders as tofu (□□) across a wide range of otherwise-healthy terminal setups. This has been reported at least five times over six months (#24102, #39127, #42948, #46909, #53080) and closed each time as stale or duplicate without a code change.
The fix is one character: U+23F5 → U+25B6 (▶, BLACK RIGHT-POINTING TRIANGLE). Visually near-identical, same width, same UTF-8 byte length, dramatically wider font coverage.
Root cause
U+23F5 sits in Miscellaneous Technical (U+2300–23FF) and has text presentation only — it is not in the Unicode emoji set. That means there is no emoji-font fallback: it renders if and only if the selected monospace font ships that specific glyph, and most don't.
The neighbouring plan-mode indicator makes the contrast exact:
| Mode | Glyph | Codepoint | In emoji set? | Renders? |
|---|---|---|---|---|
| accept edits on | ⏵⏵ | U+23F5 | No | ✗ tofu |
| auto mode on | ⏵⏵ | U+23F5 | No | ✗ tofu |
| plan mode on | ⏸ | U+23F8 | Yes | ✓ fine |
⏸ works everywhere precisely because U+23F8 PAUSE BUTTON is an emoji and falls back to the system emoji font. Same block, same Unicode version, opposite outcome. This is a property of the codepoint, not of anyone's terminal configuration.
"Just install a better font" is not a workaround
This is the standard triage response, and it does not hold. Per testing in #42948, Nerd Font patches do not reliably add U+23F5:
DejaVuSansM Nerd Font Mono— no glyph for U+23F5CaskaydiaCove Nerd Font Mono— no glyph for U+23F5- Both do have U+25B6
Geometric Shapes (U+25xx) is covered essentially universally — Consolas, Courier New, the macOS terminal defaults, and basic Linux fonts all have U+25B6. Misc Technical is not.
Affected environments reported so far
| Environment | Issue |
|---|---|
| macOS 12 Monterey — Terminal.app, iTerm2 | #42948 |
| Ubuntu 26.04 LTS — Ptyxis, xterm (with JetBrains Mono Nerd Font) | #53080 |
| Windows 11 — ConEmu + OpenSSH → WSL2/Docker | #42948 (comment) |
| Linux without fonts-symbola | #24102 |
| Termius (iOS / Android / desktop SSH client) | this report |
The Termius case is worth calling out because it is unfixable client-side, and this was verified exhaustively. Termius ships a fixed set of fonts and offers no way to install a custom or Nerd-patched one. Every available font was tested against U+23F5:
| Font | U+23F5 ⏵ | U+25B6 ▶ / U+2713 ✓ |
|---|---|---|
| Source Code Pro Medium | ✗ tofu | ✓ |
| DejaVu Sans Mono | ✗ tofu | ✓ |
| Ubuntu Mono | ✗ tofu | ✓ |
| PT Mono | ✗ tofu | ✓ |
| Cascadia Code | ✗ tofu | ✓ |
| Fira Code | ✗ tofu | ✓ |
| JetBrains Mono | ✗ tofu | ✓ |
Zero of seven available fonts render the glyph; all render the proposed replacements. U+23F8 (⏸, plan mode) renders correctly in all of them via emoji fallback. Users on this client have no remedy whatsoever until the codepoint changes — there is no font they can select, and no font they can add.
Secondary bug: two modes share one glyph
In the current mode table, acceptEdits and auto (and bypassPermissions and dontAsk) all use the same ⏵⏵ symbol, distinguished only by color:
acceptEdits: { …, symbol: "⏵⏵", color: "autoAccept" },
bypassPermissions: { …, symbol: "⏵⏵", color: "error" },
dontAsk: { …, symbol: "⏵⏵", color: "error" },
auto: { …, symbol: "⏵⏵", color: "warning" },
Even where the font renders correctly, these are indistinguishable to color-blind users and in any monochrome context (logs, screenshots, screen readers, script captures). Since bypassPermissions is the mode with the largest safety consequence, encoding it in color alone seems worth revisiting independently of the font problem.
Proposed change
Minimal — swap the codepoint:
acceptEdits: { …, symbol: "▶▶", … }, // U+25B6
auto: { …, symbol: "▶▶", … },
Optionally also differentiate the modes by shape rather than color alone, e.g. ✓✓ (U+2713, Dingbats — also near-universal) for accept-edits versus ▶▶ for auto.
Please do not use variation selector 16 (▶️ = U+25B6 U+FE0F) to force emoji presentation. That would guarantee fallback, but emoji presentation is double-width and would break TUI column alignment. Plain U+25B6 keeps width 1.
Verification
Any environment above, or reproduce the coverage gap directly:
printf 'U+23F5: ⏵\nU+25B6: ▶\nU+2713: ✓\nU+23F8: ⏸\n'
On an affected setup, line 1 is tofu while lines 2–4 render.
3 Comments
Confirming the root cause from the shipped binary, and adding the mirror-image half of this bug: the other symbol in the same table,
⏸(U+23F8), is broken for the opposite reason. Both are one-codepoint fixes in the same object literal.What's actually in the binary
From the native install (
claude.exe, 2.1.218, WinGet), the permission-mode table:So it's exactly the two codepoints named in the issue, and nothing else.
The other half:
⏸is not "fine", it's wideThe table in the issue body marks U+23F8 as "renders ✓ fine". It renders, but at the wrong width, and for the same underlying reason stated here — emoji-set membership.
On Windows Terminal with the default font (Cascadia Mono, no
font.faceoverride), the primary font has no glyph for U+23F8, so DirectWrite falls back to Segoe UI Emoji and paints a colour emoji 2 cells wide. Claude Code measures it via East_Asian_Width, where U+23F8 is Ambiguous → 1. The glyph overruns into the next column and eats the separating space:⏵never does this — not being in the emoji set means no emoji fallback, so it's either a 1-cell text glyph or tofu. Same property, two different failure modes:| Mode | Glyph | Codepoint | In emoji set | Failure |
|---|---|---|---|---|
| accept edits / auto |
⏵⏵| U+23F5 | No | tofu where the mono font lacks the glyph || manual / plan |
⏸| U+23F8 | Yes | emoji fallback renders 2 cells, measured as 1 → swallows the following space |This has been filed at least four times and closed every time without a code change: #7334, #15462, #40323, #57368, #59138. #59138 has the same diagnosis (EAW=Ambiguous, Windows Terminal, Cascadia Mono) and is now locked, so there's nowhere else to put this.
Suggested fix
Two edits in that literal:
"⏵⏵"→"▶▶"— as proposed in this issue."⏸"→"⏸︎"— append VS15 (text presentation selector) to suppress the emoji fallback and pin it to 1 cell, matching what the width calculation already assumes.The VS15 approach is already used elsewhere in the same bundle (
"\xB7✔︎\xB7"), so it's consistent with existing practice rather than a new convention. If VS15 turns out to be unreliable across terminals, U+2016 / U+23F8→||-style ASCII or another non-emoji glyph would work too — the requirement is only that the chosen codepoint is outside the emoji set, so measurement and rendering can't disagree.Environment
Reproduced the emitting side on the current release (2.1.233): capturing the terminal output directly confirms the accept-edits / auto indicators are exactly two U+23F5 code points, while plan mode uses U+23F8 — matching your analysis of why one falls back to the emoji font and the other doesn't. Whether U+23F5 renders as tofu then depends entirely on the terminal font, and your font-coverage table (including the fixed-font Termius case, where no user-side remedy exists) is persuasive.
Also confirmed your secondary point: accept-edits, auto, don't-ask, and bypass-permissions all share the same two-triangle symbol and are distinguished only by color, so in monochrome contexts or for color-blind users they are indistinguishable.
One note on the proposed replacement: U+25B6 (and U+2713) are East-Asian-Width "ambiguous" code points, which some terminal configurations render double-width, so the swap needs a width check across terminals rather than being purely mechanical — but the coverage argument for moving off U+23F5 is sound.
Flagging to the team with a recommendation to revisit the glyph choice and to consider shape (not just color) differentiation for the higher-risk modes.
🤖 Generated with Claude Code
⏵⏵ auto mode on (shift+tab to cycle) · ← for agents