鶴田研究所 Tsuruta Laboratory

調査ノート 2026-09-23

Windows日本語環境におけるClaude Codeの文字コード処理13項目の実測

Shift_JISのファイルを1語だけ直させたら、触っていない日本語が全部消えた。9種のファイルと4つの経路で、壊れるところと壊れないところを分けた記録

要旨

Claude Codeを使う開発者の多くはMacで英語を使っている。日本語のWindowsで同じ道具を使うと何が起きるかを、実際に動かして確かめた。13項目のうち9項目は正常だった。壊れたのは4項目で、いちばん重いのはShift_JISのファイルである。英単語を1つ直すよう頼むと、ファイル全体がUTF-8で書き戻され、触っていない日本語38文字がすべて置換文字(U+FFFD)に変わった。元の文字の情報は残らない。4回試して4回とも起き、モデルを変えても同じだった。1回はモデルが直後に「ほかの行はShift_JISのまま」と事実と逆の報告をした。

方法Claude Code 2.1.280を、Windows 11(システムのコードページ932)のGit Bashから、会話なしで一度だけ動かすモード(claude -p)で使った。一つ目は編集の試験で、英単語APPLEを含む9種のファイルを用意し、Editの道具でAPPLEをORANGEに替え、ほかは何も変えるなと頼んだ。判定はバイト単位で、許す差はそのファイル自身の文字コードでのAPPLEからORANGEへの置き換えだけとした。二つ目は経路の試験で、日本語のフォルダ名とファイル名の検索と読み込み、Bashで動かしたWindowsのコマンドの日本語出力、PowerShellの道具の日本語出力、Claudeに書かせた日本語入りPowerShellスクリプトの実行の4つを試した。モデルに何が届いたかは、セッションの記録ファイルに残る道具の返り値から直接読んだ。
結果9種のファイルのうち、UTF-8、BOM付きUTF-8、改行がCRLFのUTF-8、BOM付きUTF-16、タブ入り、末尾に改行が無いものの6種は正しく1語だけ変わった。Shift_JISは改行がLFでもCRLFでも、ファイル全体がUTF-8で書き戻され、日本語38文字が置換文字になった(107バイトが182バイトに)。CRLFとLFが混ざったファイルは、改行がすべてLFにそろえられた。経路の試験では、日本語のパスとPowerShellの道具は正常だった。Bashで動かした cmd の出力は、「日本語フォルダ」が「���{��t�H���_」の形でモデルに届いた。Claudeが書いたPowerShellスクリプトは、Windows標準のPowerShell 5.1で実行すると「こんにちは、世界」が「縺薙s縺ォ縺。縺ッ…」と表示された。
知見壊れ方には共通点がある。BOMという目印の付いたファイルは正しく扱われ、目印の無い古い日本語の文字コードは、すべてUTF-8として読まれる。読めない部分は置換文字になり、その状態で書き戻されるので、元に戻す手がかりが残らない。とくにShift_JISの編集では、頼んだ場所とは無関係な行まで失われる。モデル側の反応は分かれた。Opus 5.5は壊れたことに自分で気づいて別の道具で直したが、Sonnet 5は3回とも壊したまま終わり、そのうち1回は壊れていないと報告した。道具の誤りを、道具を使う側のモデルが見逃すどころか打ち消してしまう場合がある。
限界試した回数はShift_JISの編集で4回、それ以外はほとんど1回ずつで、頻度を言える数ではない。Git Bash以外のシェル、Windows 10、VS Codeの拡張機能やデスクトップアプリからの利用は試していない。Shift_JIS以外の古い文字コード(EUC-JPや中国語・韓国語のもの)も同じ扱いになると予想しているが、確かめていない。Bashの出力が化ける件は、ターミナル側の設定で避けられる可能性があり、Claude Code本体だけの問題かどうかは切り分けきれていない。

なぜ測ったか

Claude Codeの不具合の報告を読むと、ほとんどがMacかLinuxで、英語の環境である。日本語のWindowsで何が起きるかは、使っている人が少ないぶん見落とされやすい。実際、過去に似た報告はいくつか出ているが、多くは動きが無いまま自動で閉じられていた。そこで、日本語のWindowsで日常的に起きる操作を選び、壊れるかどうかを一つずつ確かめた。

編集の試験:9種のファイル

どのファイルにも英単語 APPLE を入れ、Editの道具で ORANGE に替えるよう頼んだ。ほかは1バイトも変わってはいけない。

ファイル結果
Shift_JIS、改行LFUTF-8で書き戻され、日本語38文字が置換文字に(4回中4回)
Shift_JIS、改行CRLF同上
UTF-8正常
BOM付きUTF-8正常
UTF-8、改行CRLF正常
BOM付きUTF-16、改行CRLF正常
タブ入り正常
末尾に改行なし正常
CRLFとLFが混在改行がすべてLFに変わる

Shift_JISのファイルは、編集の前後で次のように変わった。

  • 前:# 設定ファイル:ここは日本語のコメントです
  • 後:# �ݒ�t�@�C���F�����͓��{��̃R�����g�ł�

「�」は読めなかった文字の印で、元の文字の情報は入っていない。gitなどで前の版を取っておかない限り、戻す方法は無い。

モデルの反応

4回のうち3回はSonnet 5、1回はOpus 5.5で試した。壊したのはどの回もEditの道具そのもので、モデルの違いは壊れた後にだけ出た。Opus 5.5は壊れたことに気づき、PowerShellで書き直して正しい状態に戻した。Sonnet 5は3回とも壊れたまま終え、そのうち1回は「ほかの行は変わっておらず、Shift_JISのまま」と報告した。

経路の試験

試したこと結果
日本語のフォルダ名・ファイル名を、探す・読む・中身を検索する正常
Bashで cmd //c "dir /b" と cmd //c "echo 日本語テスト"モデルに置換文字で届く
PowerShellの道具で日本語を出す正常
Claudeに書かせた日本語入り .ps1 を PowerShell 5.1 で実行文字化け

Windowsのコマンドは、日本語の環境ではエラーの文面なども日本語で出す。それが置換文字で届くと、モデルは何が起きたかを推測するしかない。.ps1 の件は、BOMの無いUTF-8をPowerShell 5.1が古い文字コードとして読むために起きる。

Windowsに限らない発見:要約が消える

同じ日に、長い会話を短くまとめる機能(/compact)も試した。Sonnet 5 では、まとめ役のモデルが「会話を要約せよ」という指示を、外から紛れ込んだ命令だと疑って断り、最後の質問への答えを要約の代わりに返すことがあった。その答えが要約として保存されるので、それまでの会話は消える。会話の最初にそのセッションでの決まりを伝えた場合は3回中3回、普通の質問だけの場合は2回中1回起き、Opus 5.5では4回とも起きなかった。会話がいっぱいになって自動で要約される場合は、Sonnet 5 でも2回とも正常に要約され、決まりも残った。起きるのは、今のところ手で /compact を打ったときだけである。一方、プロジェクトのCLAUDE.mdに書いた指示は、要約が失敗した回も含めて守られた。

文字コード以外に確かめて、壊れなかったところ

試したこと結果
日本語と空白を含むフォルダにプロジェクトとプラグインを置き、フックとスキルを動かす正常
記号(& % ! ( ' $ `)を含むフォルダで同じことをする正常。ただし $ のときはモデルが自分で書いたコマンドの引用符を誤り、2回やり直した
.bat に書いた claude -p に、日本語の指示を引数とパイプで渡す正常
PowerShell 5.1 から、日本語の指示をパイプで渡すすべて「?」になる。PowerShell 5.1 がパイプに流すときの文字コードが ASCII のためで、Claude Code の不具合ではない
Stop フックが止め続けたとき、8回で打ち切られるという説明書の記述説明書どおり
フックが足せる文章は1万字までという説明書の記述説明書どおり。超えた分はファイルに退避され、モデルには先頭2,000字だけが見える

パスの扱いやフックの受け渡しは、日本語や記号に対してかなり丈夫だった。壊れやすいのは、ファイルの中身とコマンドの出力の文字コードに集中している。

報告

次の3件をClaude Codeの開発元に報告した。

  • Shift_JISのファイルを編集すると日本語が置換文字で消える(anthropics/claude-code #96263)
  • Bashで動かしたコマンドの日本語出力が置換文字で届く(#96271)
  • Sonnet 5 で要約が拒否され会話が消える(#96261)

.ps1 の件はすでに報告があった(#90962)ので、新しくは出していない。改行の混在の件は影響が小さいので報告していない。

日本語のWindowsで使うときの当面の対策

  • Shift_JISのファイルをClaude Codeに直させる前に、gitに入れておく。できればUTF-8に変換してから渡す。
  • Windowsのコマンドの出力を読ませたいときは、BashではなくPowerShellの道具で動かす。
  • PowerShell 5.1で動かすスクリプトは、BOM付きUTF-8で保存し直す。
  • 会話の中で決めた大事な決まりは、会話に残さずCLAUDE.mdに書く。
  • PowerShell 5.1 から日本語の指示をパイプで渡すときは、先に $OutputEncoding = [Text.Encoding]::UTF8 を実行する。引数で渡せばこの問題は起きない。

資料