[Bug] Garbled characters (mojibake) in CLI output since v2.1.86

Status Closed — not planned
Reported on v2.1.86
Maintainer reply None cached
Activity 11 comments · opened Mar 29, 2026 · closed Jul 11, 2026

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:

  1. Use Claude Code in a Chinese-language conversation
  2. Ask it to generate longer text outputs containing CJK

characters

  1. 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:

  1. Use Claude Code in a Chinese-language conversation
  2. Ask it to generate longer text outputs containing CJK

characters

  1. 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_

View original on GitHub ↗

11 Comments

m-itoi · 5 months ago

Same issue here with Japanese characters on Linux (WSL2).

  • Claude Code version: 2.1.87
  • OS: Linux (WSL2, 6.6.87.2-microsoft-standard-WSL2)
  • Terminal: VS Code Terminal
  • Shell: zsh

In addition to conversation output, we also see corruption in Edit tool output (file writes). Example:

  • Expected: リクエスト値
  • Actual: リクエス���値 (「ト」corrupted to U+FFFD)

Happens intermittently, multiple times per session.

MU5K · 5 months ago

Same version range (v2.1.86+), different symptom on Windows + Git Bash (MSYS2).

Environment

  • Claude Code: 2.1.89
  • OS: Windows 11 Pro (26200.8117)
  • Terminal: Windows Terminal / VS Code integrated terminal
  • Shell: Git Bash (MSYS2 MINGW64)
  • Locale: LANG=ja_JP.UTF-8, system codepage 932

Symptom

Emoji characters in conversation output are replaced with (U+25C6 black diamond) — not U+FFFD as 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=msys
  • MSYSTEM=MINGW64
  • TERM=xterm-256color
  • TERM_PROGRAM= (empty)
  • COLORTERM= (empty)
  • WT_SESSION= (set — confirms running inside Windows Terminal)

PowerShell likely has TERM_PROGRAM or other vars set that signal emoji support. The absence of these in Git Bash may trigger the fallback.

Notes

  • Shell prompt (oh-my-posh with Nerd Font) renders emoji correctly — this is not a terminal/font issue
  • File writes via Edit/Write tools are not affected — only conversation output
  • The fallback character (rather than U+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+).
MU5K · 5 months ago

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.

MU5K · 5 months ago

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.

MU5K · 4 months ago

<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 --version returned v2.1.91. In this state, none of the following symptoms occurred:

  • Emoji → substitution
  • Echo/duplicate rendering
  • Status bar splitting across two lines

The 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.

Astro-Han · 4 months ago

+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.

noahfestifriend · 3 months ago

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.

paperdyno · 3 months ago

Resizing terminal horizontally fixes the issue, at least temporarily.

ljpsfree · 3 months ago

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_DIR is 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.

stankitsis · 2 months ago

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

  • Claude Code v2.1.163 (latest at time of writing), installed via npm
  • Node v22.22.3
  • Running INSIDE a Docker dev container; VS Code integrated terminal (TERM_PROGRAM=vscode, TERM=xterm-256color)
  • WSL2 host
  • Container locale: C.UTF-8 (UTF-8 round-trips correctly at the shell)

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 bytes c3 a2 c2 80 c2 94.
That is e2 80 94 decoded as ISO-8859-1 -> codepoints U+00E2 U+0080 U+0094 -> re-encoded as UTF-8.
The fact that 0x94 maps 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-1 on the copied text restores the original.

Isolation (this is Claude's output, not the terminal/clipboard/locale)

  1. Copying the SAME characters from 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.
  2. Claude Code's Write tool produces clean UTF-8 files (verified with od).
  3. Only the terminal-render -> clipboard copy of Claude's OWN output is corrupted.

Repro

  1. In the Claude Code TUI, have Claude print text containing an em-dash (U+2014) or box-drawing chars.
  2. Select that output with the mouse and copy.
  3. Paste into any other app, or into cat > /tmp/x and run od -An -tx1 /tmp/x.
  4. Observe c3 a2 c2 80 c2 94 instead of e2 80 94.
  5. Control: do the same with cat <utf8-file> output as the copy source -> bytes are correct.
github-actions[bot] · 1 month ago

Closing for now — inactive for too long. Please open a new issue if this is still relevant.