[Bug] Garbled characters (mojibake) in CLI output since v2.1.86
Preflight Checklist
- [x] I have searched existing issues and this hasn't been reported yet
- [x] This is a single bug report (please file separate reports for different bugs)
- [x] I am using the latest version of Claude Code
What's Wrong?
Environment:
- Claude Code version: 2.1.86+
- OS: macOS (Darwin 25.3.0)
- Terminal: [iTerm2 / Terminal.app / VS Code Terminal]
- Shell: zsh
- Locale: UTF-8
Description:
Since upgrading to v2.1.86, Chinese characters in
Claude's text output are intermittently rendered as ��
(U+FFFD replacement characters). This happens in the
conversation output (not in file writes — generated code
files are correct).
Example:
- Expected:
LLM 调用工具 "dashscope_web_search" - Actual:
LLM ��用工具 "dashscope_web_search"
The corrupted character is 调 (U+8C03), a common CJK
character. It appears to be a multi-byte UTF-8
truncation issue where a 3-byte sequence gets split at a
chunk boundary.
Frequency: Intermittent, occurs multiple times per
session, across different conversations. Affects only
terminal rendering — files written via Write/Edit tool
are not corrupted.
Steps to reproduce:
- Use Claude Code in a Chinese-language conversation
- Ask it to generate longer text outputs containing CJK
characters
- Observe random
��replacements in the streamed
output
Suspected cause: SSE streaming chunk boundary
splitting multi-byte UTF-8 sequences.
What Should Happen?
Environment:
- Claude Code version: 2.1.86+
- OS: macOS (Darwin 25.3.0)
- Terminal: [iTerm2 / Terminal.app / VS Code Terminal]
- Shell: zsh
- Locale: UTF-8
Description:
Since upgrading to v2.1.86, Chinese characters in
Claude's text output are intermittently rendered as ��
(U+FFFD replacement characters). This happens in the
conversation output (not in file writes — generated code
files are correct).
Example:
- Expected:
LLM 调用工具 "dashscope_web_search" - Actual:
LLM ��用工具 "dashscope_web_search"
The corrupted character is 调 (U+8C03), a common CJK
character. It appears to be a multi-byte UTF-8
truncation issue where a 3-byte sequence gets split at a
chunk boundary.
Frequency: Intermittent, occurs multiple times per
session, across different conversations. Affects only
terminal rendering — files written via Write/Edit tool
are not corrupted.
Steps to reproduce:
- Use Claude Code in a Chinese-language conversation
- Ask it to generate longer text outputs containing CJK
characters
- Observe random
��replacements in the streamed
output
Suspected cause: SSE streaming chunk boundary
splitting multi-byte UTF-8 sequences.
Error Messages/Logs
Steps to Reproduce
2.1.86
Claude Model
None
Is this a regression?
Yes, this worked in a previous version
Last Working Version
_No response_
Claude Code Version
2.1.86
Platform
Anthropic API
Operating System
macOS
Terminal/Shell
Terminal.app (macOS)
Additional Information
_No response_
11 Comments
Same issue here with Japanese characters on Linux (WSL2).
In addition to conversation output, we also see corruption in Edit tool output (file writes). Example:
リクエスト値リクエス���値(「ト」corrupted to U+FFFD)Happens intermittently, multiple times per session.
Same version range (v2.1.86+), different symptom on Windows + Git Bash (MSYS2).
Environment
LANG=ja_JP.UTF-8, system codepage 932Symptom
Emoji characters in conversation output are replaced with
◆(U+25C6 black diamond) — notU+FFFDas reported in the original issue. CJK text renders correctly; only emoji is affected.Example:
📋 月次リマインド→◆ 月次リマインドKey finding: Git Bash only
On the same machine, same Windows Terminal window:
| Shell | Result |
|---|---|
| Git Bash (MSYS2) | Emoji →
◆(broken) || PowerShell 7.6 | Emoji renders correctly |
This suggests Claude Code's terminal capability detection treats MSYS2/Git Bash differently and falls back to a non-emoji character set.
Relevant env vars in Git Bash
OSTYPE=msysMSYSTEM=MINGW64TERM=xterm-256colorTERM_PROGRAM=(empty)COLORTERM=(empty)WT_SESSION=(set — confirms running inside Windows Terminal)PowerShell likely has
TERM_PROGRAMor other vars set that signal emoji support. The absence of these in Git Bash may trigger the fallback.Notes
◆fallback character (rather thanU+FFFD) suggests a deliberate emoji→symbol substitution path, not a UTF-8 chunk boundary issue as described in the original report. These may be two separate bugs sharing the same version trigger (v2.1.86+).Follow-up: Additional TUI rendering issues on the same Git Bash environment.
Beyond the emoji →
◆substitution reported above, there are broader rendering problems in Git Bash (MSYS2) since v2.1.86+:1. Echo/duplicate rendering ("yamabiko")
Conversation output is rendered twice — scrolling back reveals the same content duplicated. This is visible from the scrollbar length being much longer than expected. Likely the ink rendering buffer is double-flushing against the Git Bash PTY.
2. TUI element corruption (intermittent, observed on v2.1.87)
Tool status indicators render as garbled text — e.g., tool names replaced with "Jitterbugging…", layout collapsing. This was observed in VS Code + Git Bash on 2026-03-31 but is not consistently reproducible as of v2.1.89.
Current state (v2.1.89)
| Symptom | Status |
|---|---|
| Emoji →
◆| Still occurring || Echo/duplicate rendering | Still occurring |
| TUI element corruption | Improved, not currently observed |
All symptoms are Git Bash (MSYS2) only — PowerShell 7.6 on the same machine and same Windows Terminal does not exhibit any of these issues.
Reproduction steps for the echo issue are not yet pinpointed — it is noticed when scrolling back through conversation history. It may be related to output length or parallel tool execution.
Addendum: One more symptom on the same Git Bash (MSYS2) environment.
3. Status bar splitting across two lines
The bottom status bar (model name, cost, diff stats, branch, file indicator, timer) splits into two rows instead of rendering on a single line. This suggests the terminal width calculation is off — likely because emoji and/or multi-byte characters are counted differently by the ink renderer vs the Git Bash PTY.
This is also Git Bash only — PowerShell renders the status bar on a single line as expected.
<img width="1373" height="1168" alt="Image" src="https://github.com/user-attachments/assets/4b601de0-b879-4b1e-ba30-8c723477779b" />
Additional finding: v2.1.76 renders correctly on the same environment
On a dormant Windows account, the VS Code extension launched Claude Code with its older bundled version (v2.1.76), while
claude --versionreturned v2.1.91. In this state, none of the following symptoms occurred:◆substitutionThe OS, terminal (Windows Terminal + Git Bash / MSYS2), shell, locale, and font are identical to the environment where v2.1.86+ consistently exhibits all of the above symptoms. The only difference is the version of Claude Code's TUI rendering code being executed.
This narrows the regression window to v2.1.76 → v2.1.86.
+1. macOS (Darwin 25.3.0), Terminal.app, CLI latest, Chinese (Simplified).
Same U+FFFD corruption in streaming output. Consistent with the UTF-8 byte-boundary splitting described in #39593. File writes via Edit/Write tools are fine, only TUI rendering affected.
I have a video of this happening in real time... Maybe not the same issue but it's really strange and may be related.
This is MacOS and using a VS Code terminal window fullscreened.
https://youtu.be/vnuf02XlfYk
It clears up when I point it out to Claude... so Idk if it is just a corrupted stream or what but it happens relatively often for me. Like every few days or so.
Resizing terminal horizontally fixes the issue, at least temporarily.
I'm running into a related but slightly different variant of this bug. My setup: macOS Darwin 25.3.0, iTerm2 3.6.10, zsh, locale UTF-8.
The issue only appears in background agents mode (when
$CLAUDE_JOB_DIRis set). In a regular interactive session, Chinese text displays and copies correctly. In an agents session, the text on screen looks correct, but when I select and copy it, the clipboard ends up with double-encoded bytes.I verified with
pbpaste | xxd(screenshot attached): instead of the expected UTF-8 bytes (e.g., E4 B8 AD for 中), the clipboard has each original byte re-encoded as a separate UTF-8 2-byte sequence (e.g., c3 84 c2 b8 c2 ad). The pattern is consistent with each raw byte being interpreted as a Latin-1 code point and then re-encoded as UTF-8.The same text copied from the normal scrollback after exiting the agent view comes out correctly. So the bug seems to be in the rendering path specific to the agents TUI, not in the underlying output — I captured the raw PTY output and the bytes Claude Code writes to the terminal are correct UTF-8.
Workaround for now: exit the agent view before copying.
Still present in v2.1.163: text copied FROM Claude Code's terminal output is double-encoded UTF-8 (lossless UTF-8 -> ISO-8859-1 -> UTF-8). Displays correctly on screen; corrupts only on copy.
Environment
Symptom
Multibyte UTF-8 in Claude Code's terminal output (em-dash, box-drawing, smart quotes, arrows, ellipsis) RENDERS correctly on screen, but when selected and copied it lands on the clipboard double-encoded. Pasting it anywhere (another Claude window, another terminal, an editor, Notepad) yields mojibake.
Byte-level evidence
Em-dash U+2014 (correct UTF-8 bytes
e2 80 94) is copied out as bytesc3 a2 c2 80 c2 94.That is
e2 80 94decoded as ISO-8859-1 -> codepoints U+00E2 U+0080 U+0094 -> re-encoded as UTF-8.The fact that
0x94maps to U+0094 (a raw C1 control) shows it is ISO-8859-1, not CP1252.Same pattern for box-drawing (e.g. U+2500
e2 94 80->c3 a2 c2 94 c2 80), arrows, smart quotes, ellipsis.It is fully reversible:
iconv -f UTF-8 -t ISO-8859-1on the copied text restores the original.Isolation (this is Claude's output, not the terminal/clipboard/locale)
cat <file>output in the SAME VS Code terminal -> clipboard is byte-perfect (e2 80 94 ...). So the terminal, clipboard, and paste path are clean.od).Repro
cat > /tmp/xand runod -An -tx1 /tmp/x.c3 a2 c2 80 c2 94instead ofe2 80 94.cat <utf8-file>output as the copy source -> bytes are correct.Closing for now — inactive for too long. Please open a new issue if this is still relevant.