Claude CodeでShift-JISを編集できない原因とUTF-8変換の手順
Editツールが「File is not valid UTF-8」で拒否される理由と、Shift-JIS・Windows-1252のファイルを文字化けさせずに直す2つの方法を、iconvの実行例つきで説明します。
Shift-JISで保存された既存システムのソースをClaude Codeに直させると、Editツールが File is not valid UTF-8 を返して止まることがあります。ファイルは壊れていません。Claude Codeが、書き込めば文字化けすると判断して拒否しただけです。直し方は2つあります。ファイルの文字コードのまま変更する方法と、いったんUTF-8に変換してからEditに任せる方法です。
「File is not valid UTF-8」は何を拒否しているのか
エラー本文は次のとおりです。ツールの結果としてClaudeに返ります。
File is not valid UTF-8. It may use a legacy encoding such as Windows-1252, Shift-JIS or GBK, or be binary. This tool saves the whole file as UTF-8, which would replace every byte it cannot decode with U+FFFD. Nothing was written. Make the change with a shell command that reads and writes the file in its own encoding, or ask the user whether to convert the file to UTF-8 first.EditとNotebookEditは、編集後にファイル全体をUTF-8で保存し直します。UTF-8として読めないバイトがあると、それらはすべて置換文字 U+FFFD に化けます。Shift-JISの日本語はほぼ全文字が該当するので、一部の編集のつもりが全行の文字化けになりかねません。そこで書き込み前に検査し、読めなければ何も書かずに拒否します。
拒否の対象は、Windows-1252やShift-JISなどレガシー文字コードの非ASCIIテキスト、バイナリ、そしてUTF-8のつもりで1か所だけ不正なバイト列が混じったファイルです。検査はファイル全体のバイト列に対して行われるため、たった1バイトの不正でも拒否されます。
拒否されるファイルの 3 タイプ
レガシー文字コード
Shift-JIS、Windows-1252、GBKなどで保存された、非ASCIIを含むテキストです。
バイナリ
画像や圧縮ファイルなど、テキストではないファイルです。
UTF-8 のつもりで壊れたファイル
不正なバイト列が1つ混じっているだけでも、ファイル全体が対象になります。
ASCIIだけで書かれたShift-JISファイルは、そのままUTF-8としても読めるので拒否されません。日本語コメントや文字列リテラルを含むファイルで初めてこのエラーに当たります。UTF-16には例外があります。Editに限り、リトルエンディアンのBOMで始まるファイルは拒否の対象外です(NotebookEditには例外がありません)。
Claude Codeのバージョンで挙動が違う
この拒否はv2.1.296(2026年10月9日)で入りました。changelogには「UTF-8でないファイル(Windows-1252、Shift-JIS、GBK)で、EditとNotebookEditが非ASCII文字をすべて置換していた問題を修正。そうした編集は拒否される」とあります。
v2.1.296より前のバージョンは逆です。拒否されないまま編集が適用され、デコードできなかったバイトは U+FFFD として保存されました。「エラーが出ない古いバージョンのほうが楽だった」と感じても、エラーを出さずにファイルが壊れていた、ということです。エラーが出たなら、先に claude --version でバージョンを確かめてください。
claude --version古いバージョンで、すでにShift-JISファイルをEditに触らせてしまった場合は、U+FFFD が混じっていないかをバージョン管理の差分で確かめてください。
直し方1: 文字コードを保ったまま変更する
エラー本文がClaudeに指示しているのは、この方法です。ファイルの文字コードで読み書きするシェルコマンドを使います。既存システムのShift-JISを維持したいなら、こちらが基本です。
legacy/customer.txt は Shift-JIS です。Edit は使わず、
iconv で UTF-8 に変換して sed で置換し、Shift-JIS に戻して保存してください。実際に動かして確かめた例です(Shift-JISで 顧客名=山田 と保存した小さなテキストを使用)。
iconv -f SHIFT_JIS -t UTF-8 sjis.txt \
| sed 's/山田/鈴木/' \
| iconv -f UTF-8 -t SHIFT_JIS > out.txt
iconv -f SHIFT_JIS -t UTF-8 out.txt最後のコマンドは 顧客名=鈴木 と表示します。出力ファイルがShift-JISのままであることは、xxd で見た先頭バイトが 8cda(「顧」のShift-JIS表現)になっていることで確かめられます。ここで > out.txt を経由しているのは、同じファイルへ直接リダイレクトすると、読む前に中身が空になるためです。置き換えるのは出力を確かめてからにしてください。
この方法の要点は、変更をClaudeに任せる前に、文字コードを指定する指示を渡すことです。毎回書くのが面倒ならCLAUDE.mdに書いておけます。
# 文字コード
- src/legacy/ 以下の .txt と .cob は Shift-JIS(CRLF)。
- Edit は使わない。iconv で変換してから置換し、同じ文字コードで書き戻す。
- 変更後は iconv -f SHIFT_JIS -t UTF-8 で読み直し、文字化けがないか確かめる。これは筆者が考えた記述例で、パスや拡張子はプロジェクトに合わせて変えてください。
Windows由来のファイルはCP932を指定する
SHIFT_JIS のまま変換して失敗するファイルがあります。Windowsで作られたファイルには、丸数字(①)、㈱、「髙」のような機種依存文字が入っていることがあり、これらは標準のShift-JISに含まれません。実機で 顧客名=①㈱髙 をCP932(WindowsのShift-JIS)で保存して試したところ、SHIFT_JIS を指定した変換は次のエラーで止まりました。
iconv -f SHIFT_JIS -t UTF-8 win.txt顧客名=iconv: iconv(): Illegal byte sequence同じファイルを -f CP932 で読むと、顧客名=①㈱髙 と最後まで表示されました(MS932 でも同じ扱いです)。直し方1のコマンドは、-f と -t の両方を CP932 に替えれば、そのまま使えます。
iconv -f CP932 -t UTF-8 win.txt \
| sed 's/山田/鈴木/' \
| iconv -f UTF-8 -t CP932 > out.txtどちらか迷うときはCP932を先に試すのが安全です。CP932はShift-JISの上位互換として、標準のShift-JISの文字も読めます。
直し方2: UTF-8に変換してからEditに任せる
もう1つは、ファイル自体をUTF-8にして、以後は通常どおりEditを使えるようにする方法です。ただし、そのファイルを読む側(コンパイラ、取り込みバッチ、他システム)がUTF-8に対応していることが前提です。変換は1回で終わらせ、結果を確認してから進めます。
Shift-JIS から UTF-8 への変換手順
- 1
現在の文字コードを調べる
file -Iやfile --mime-encodingで見当をつけます。短いファイルでは誤判定もあるため、結果は目安として扱います。 - 2
バックアップを取る
変換前のファイルを別名で保存します。
- 3
iconv で変換する
iconv -f SHIFT_JIS -t UTF-8 元 > 新の形で出力します。変換できない文字があればiconvがエラーを返します。Windows由来で①・㈱・髙などを含むなら、SHIFT_JISではなくCP932を指定します。 - 4
読み直して確認する
U+FFFD(�)が混じっていないか、日本語が想定どおり表示されるかを見ます。 - 5
Claude に編集を頼み直す
UTF-8になったファイルならEditが受け付けます。
cp customer.txt customer.txt.bak
iconv -f SHIFT_JIS -t UTF-8 customer.txt.bak > customer.txtWindows-1252のファイルなら -f を WINDOWS-1252 に、Windows由来のShift-JISなら CP932 に替えます。変換するとファイルのバイト列がほぼ全行で変わるため、バージョン管理の差分が大きくなる点も見込んでおいてください。変更の中身を見たい場面では、直し方1のほうが差分を小さく保てます。
文字コードの判定は file だけに頼らない
実機で試したところ、Shift-JISの短いテキストに対して file は「DOS executable」と答え、文字コードは unknown-8bit になりました。短いファイルの判定は当てになりません。
UTF-8として読めるかどうかなら、iconv -f UTF-8 -t UTF-8 ファイル > /dev/null の終了コードで検査できます。上のShift-JISファイルでは終了コードが1でした。Editが拒否する条件(UTF-8として読めない)と同じ観点なので、Claudeに頼む前の事前検査に向いています。
UTF-8のはずなのに拒否されるファイルは、不正なバイトの位置を探します。手元のmacOSのiconvは、失敗しても iconv: iconv(): Illegal byte sequence と出すだけで位置を教えてくれません。iconvの実装によって出力は異なるため、位置はcmpで確かめるのが確実です。次のように -c(変換できない文字を捨てる)の出力と元のファイルを cmp で比べると、最初に食い違う位置が分かります。
iconv -c -f UTF-8 -t UTF-8 bad.txt | cmp - bad.txt
xxd -s 3 -l 8 bad.txtstdin bad.txt differ: char 5, line 2
00000003: 0a8c da3d 780a 6c61 ...=x.lachar 5 は1始まりの位置なので、先頭から5バイト目(オフセット4)に当たる 8c が不正なバイトです。2行目の頭にある 8cda は、Shift-JISの「顧」でした。UTF-8ファイルに別の文字コードの行が混じっていた例で、その行だけUTF-8で打ち直すか、iconv で変換し直せば解消します。
Writeで全体を書き換えるのは近道ではない
Editが拒否しても、Writeならファイルを丸ごと置き換えられる場合があります。ただし2つの制約があります。
- 新しい内容に
U+FFFDが含まれていると拒否されます。Readがデコードできないバイトの代わりにClaudeに見せる文字なので、化けたテキストをそのまま書き戻す事故を防ぐ仕組みです - 置き換えに成功したときは、新しい内容がUTF-8で保存されます。つまり元の文字コードは失われます
Shift-JISを維持したいファイルをWriteで書き換えると、読んでいるシステムが壊れる可能性があります。Writeは、文字コードが変わってよいファイルに限って使う手段です。
NotebookEditも同じ規則に従う
NotebookEditは、UTF-8として読めないノートブックファイルを同じ条件で拒否し、何も書きません。.ipynb はふつうUTF-8のJSONなので、このエラーに当たるのは文字コードが壊れた場合に限られます。ノートブック編集の仕組みはClaude CodeでJupyterノートブックを編集する仕組みにあります。
切り分けの早見表
| 状況 | 起きていること | 次の一手 |
|---|---|---|
| 日本語を含む既存ファイルで拒否された | 起きていることShift-JISなどレガシー文字コードの可能性が高い | 次の一手直し方1か2を選ぶ |
| UTF-8のはずのファイルで拒否された | 起きていること不正なバイト列が1か所でも混じっている | 次の一手iconv -c と cmp で位置を探し、修正する |
| ASCIIだけのファイルで編集が失敗する | 起きていることこのエラーではない | 次の一手別の原因を調べる |
| エラーが出ずに文字が化けた | 起きていることv2.1.296より前のバージョン | 次の一手更新し、化けた箇所を差分で戻す |
エラーメッセージの文字列が違う編集失敗は別の問題です。タブインデントで失敗する場合はClaude Codeでタブ編集できないエラーの原因と対処法を参照してください。
よくある質問
CRLF改行のファイルをiconvで変換すると、改行はどうなりますか
変換前後で改行コードは変わりません。実機で 顧客名=1 にCRLFを付けたUTF-8ファイルをCP932に変換したところ、末尾は 0d0a のまま残りました。iconvが変えるのは文字のバイト列だけです。CRLFをLFに直したいときは、別の工程で行います。