Claude Code で日本語が文字化けする問題に遭遇した話
目次
どうも白澤です。もう 3 月ですね、今年もあっという間です。
今回は Claude Code を使っていて遭遇した日本語の文字化け問題について書いていきます。結構ハマったので共有がてら。
発生した環境
| 項目 | 値 |
|---|---|
| Claude Code | v2.1.62 → v2.1.63 |
| Node.js | v25.6.1(2026-02-26 にインストール) |
| ターミナル | VS Code 1.109.5 (xterm-256color) |
| ロケール | en_US.UTF-8 |
| OS | macOS (Darwin 25.3.0) |
| API プロキシ | Cloudflare AI Gateway(ANTHROPIC_BASE_URL) |
この組み合わせで Claude Code を使うと、日本語が高確率で文字化けするという問題に遭遇しました。先週まで普通に動いていたのに突然発生するようになったので、最初は何が起きたのかよくわかりませんでした。
どんな感じで文字化けするのか
実際に文字化けしていた Claude Code のレスポンスがこんな感じです。
つまり、今まさにこの会話で問題が再現��ているということ���すね。
これはCloudflare AI Gatewayを経由している現在のセッション内で
リアルタイムに起きているので、やはりClaude Codeのストリーム処理が原因だと考えられます。
ただし一点注意として、先ほどのcurlテストはGatewayを経���していません
(api.anthropic.com 直接)。一方、この会話は ANTHROPIC_BASE_URL 経由
(Gateway経由)です。
Gatewayバイパスのテストは別のClaude Codeセッションで試しました���?
もしこのセッション内で環境変数を変えた���けだと、
セッション起動時の設定が使われ続けている可能性があります��
見事に � に化けていますね、、、日本語のマルチバイト文字がごっそり消えたり化けたりしていて、まともに読める状態ではなくなっています。
調査プロセス
原因の切り分けのために、いくつかのパターンで検証を行いました。
Step 1: Tailscale の切断
Tailscale を使っていたので、まずネットワーク経路を疑って Tailscale をオフにして検証しました。
結果としては文字化けに変化なし。Tailscale は無関係でした。
Step 2: Cloudflare AI Gateway のバイパス
次に Gateway を疑って、直接 Anthropic API に接続してみました。
ANTHROPIC_BASE_URL= claude
結果としては文字化けの頻度は下がったものの、完全には解消しませんでした。Gateway は悪化要因ではあるけど、唯一の原因ではないということです。
Step 3: Node.js バージョンの切り替え
Node.js v25.6.1 は 2026-02-26 にインストールしたもので、ちょうど問題の発生時期と一致していたので怪しいなと。mise で Node.js v22(LTS)に切り替えて検証しました。
mise use node@22
ただ、Gateway ありの状態では依然として文字化けが発生。Node.js 単体の変更だけでは解消しないことがわかりました。
Step 4: ターミナル・Claude Code バイナリの検証
VS Code のターミナル以外にも WezTerm、Ghostty など複数のターミナルで試しましたが、どれでも同様に文字化けが発生。Nix でインストールしたものと公式の curl インストールでも比較しましたが、どちらでも発生。ターミナルのレンダリングやバイナリソースは無関係ということがわかりました。
Step 5: curl で直接 API を叩いて検証
Claude Code を完全にバイパスして、curl で Anthropic API に直接ストリーミングリクエストを送信。
curl -s "https://api.anthropic.com/v1/messages" \
-H "content-type: application/json" \
-H "x-api-key: $ANTHROPIC_API_KEY" \
-H "anthropic-version: 2023-06-01" \
-d '{
"model": "claude-sonnet-4-20250514",
"max_tokens": 200,
"stream": true,
"messages": [{"role": "user", "content": "日本語で短い挨拶を3つ書いてください"}]
}'
レスポンスは完全に正常で、文字化けなし。Anthropic API のレスポンス自体には問題がなく、クライアント側の処理に原因があることが確定しました。
Step 6: 両方の要因を同時に除去
ANTHROPIC_BASE_URL を空にし、かつ Node.js v22 に切り替えて検証。
ANTHROPIC_BASE_URL= claude # Node 22 環境で実行
文字化けが発生しなくなりました。
検証結果のまとめ
| 条件 | 文字化け |
|---|---|
| Node 25 + Gateway あり | 高頻度で発生 |
| Node 25 + Gateway なし | 低頻度で発生 |
| Node 22 + Gateway あり | 低〜中頻度で発生 |
| Node 22 + Gateway なし | 発生しない |
| curl 直接(Claude Code 不使用) | 正常 |
対処法
先に結論を書いておくと、以下の 2 つを両方とも 対処することで発生しなくなりました。
ANTHROPIC_BASE_URLを空欄にする(Cloudflare AI Gateway を経由しない)- Node.js 22 にダウングレードする
# .zshrc / .bashrc / mise の設定
# export ANTHROPIC_BASE_URL=https://gateway.ai.cloudflare.com/... # コメントアウト
上の検証結果からわかるように、2 つの原因は独立して文字化けを引き起こすので、どちらか一方だけ対処しても完全には解消しません。両方やって初めて文字化けが発生しなくなります。
原因の詳細
調べてみたところ、原因として考えられるものが大きく 2 つありました。
1. Node.js 24+ の fast-utf8-stream.js バグ
結構根深い話で、Node.js の内部モジュールである fast-utf8-stream.js にバグがあるようです。このモジュールは SonicBoom ライブラリから 2026 年 1 月にポートされたもので、releaseWritingBuf() が fs.write の返すバイト数をそのまま文字列のスライス位置に使ってしまうのが根本原因です。
これの何が問題かというと、バイト数と文字数が一致しない UTF-8 のマルチバイト文字で破綻するということです。特にストリーミング中のバックプレッシャー発生時に問題が顕在化します。
- 3 バイト文字(日本語・中国語・韓国語など)→ 無言で消失
- 4 バイト文字(絵文字など)→ 不正なサロゲートが残る
修正 PR(nodejs/node#61745 ↗)は提出済みですが、マージ状況は要確認です。バグ報告は nodejs/node#61744 ↗ にあります。
2. Cloudflare AI Gateway の SSE 再チャンキング
Cloudflare AI Gateway を Proxy として使う場合、SSE ストリームを中継する際にレスポンスのチャンクが再分割されます。この再分割がマルチバイト UTF-8 文字の途中で行われると、文字境界が崩れて文字化けが発生します。
Cloudflare コミュニティでも SSE ストリーミングのバッファリング問題 ↗やチャンキング破損 ↗が報告されています。
Claude Code 側の問題
上記に加えて、Claude Code の SSE パーサーが TextDecoder の { stream: true } オプションを適切に使用していない可能性があります。
// stream: true にすると、パーシャルなマルチバイトシーケンスをバッファリングしてくれる
const decoder = new TextDecoder("utf-8");
decoder.decode(chunk, { stream: true });
この { stream: true } オプションはパーシャルなマルチバイトシーケンスをバッファリングする機能で、これを使わないとチャンク境界でマルチバイト文字が分断された場合に文字化けが起きます。これは Claude Code 固有の問題ではなく、SSE ストリーミングを消費する全てのアプリケーションに共通しうる問題です。
なぜ両方の対処が必要なのか
2 つの原因は独立して文字化けを引き起こします。
- Node 24+ 単体:
fast-utf8-stream.jsのバグにより、バックプレッシャー発生時に 3 バイト文字が消失 - AI Gateway 単体: SSE 再チャンキングにより文字境界が分割され、Claude Code のストリームパーサーで置換文字が発生
- 両方: 2 つの要因が重なり、文字化け頻度が大幅に上昇
だから片方だけ除去しても低頻度で文字化けが発生し続けるわけです。
影響範囲
| 影響を受けるユーザー | 条件 |
|---|---|
| 確実に影響 | CJK 言語 + Node 24+ + AI Gateway 経由 |
| 低頻度で影響 | CJK 言語 + Node 24+(Gateway なし) |
| 低頻度で影響 | CJK 言語 + Node 22 + AI Gateway 経由 |
| 影響なし | ASCII/Latin 文字のみのユーザー |
| 影響なし | CJK 言語 + Node 22 + Gateway なし |
今後のリスク
この問題、今のうちに認識しておいた方が良さそうです。
- Node.js 24 は 2026 年 10 月に LTS になる予定で、そうなると Node.js 22 からの移行が進み、
fast-utf8-stream.jsバグの影響範囲が大幅に拡大する - Cloudflare AI Gateway は公式に Anthropic をサポートしており、利用者は増加傾向にある
つまり、LTS になったタイミングで一気に影響を受ける人が増える可能性があるということです。Node.js 24 にアップグレードしたら日本語が化けるようになった、みたいな報告が増えそうな予感がします。
まとめ
ということで、Claude Code + Cloudflare AI Gateway + Node.js 24 の組み合わせで日本語が文字化けする問題について書きました。
現時点での対処法としては Gateway を経由しないことと Node.js 22 を使うことの両方を行うのが確実ですが、根本的には Node.js 側の修正 PR がマージされるのを待つのが良さそうです。
AI ツールを日本語環境で使っていると、こういうマルチバイト文字特有の問題に遭遇することがたまにありますね。英語圏だと気づかないバグが日本語だと顕在化するパターン、結構あるあるだと思います。同じ問題に遭遇した方の参考になれば幸いです。