ToDo に「表記を揃える」を追加して
☐ 表記を揃える
表記を諿える ではなく
UTF-8 Guard for Claude
Claude Code のツール呼び出しで日本語、韓国語、中国語が別の文字に化けるのを防ぎます。Claude はこれらを \uXXXX エスケープで書いて 16 進数を間違えたり、似た別の漢字を書いたりします。このプラグインは UTF-8 のまま書くよう伝え、壊れて見える呼び出しを一度止めます。
このプラグインがないと、上の ToDo は 表記を諿える と書かれることがあります。#54051 で報告された置き換えで、実在する漢字ですが間違った文字です。
インストール
Claude Code のターミナルのプロンプトで:
/plugin install utf8-guard --marketplace M1nu0x0/claude-utf8-guardAdd marketplace? に y と答え、scope は user を選びます。PATH に Node.js 18 以上が必要です。
シェルからは:
claude plugin install utf8-guard --marketplace M1nu0x0/claude-utf8-guardClaude Desktop では、プロンプト横の + → Plugins → Add marketplace に M1nu0x0/claude-utf8-guard を入力し、utf8-guard を追加します。次のセッションから適用されます。
前と後
tool_use AskUserQuestion {"question": "表記を諿えますか?"}
card 表記を諿えますか?utf8-guard 諿 (U+8AFF): JIS X 0208 にない漢字
tool_use AskUserQuestion {"question": "表記を揃えますか?"}
card 表記を揃えますか?作った理由
AskUserQuestion、TodoWrite、Notion や Jira の MCP ツールなどのツール呼び出しで、Claude が韓国語を文字ではなく \uXXXX エスケープで書くことがあります。16 進数を 1 桁間違えても実在する音節にデコードされるため、誰かが読むまで壊れていることに気づきません。
日本語でも起きています。#54051 は Notion MCP の呼び出しで 揃え が 諿え、処分 が 処勭、側 が簡体字の 侧 になったと報告し、#59649 は AskUserQuestion で 叩き が 鯰し、再起動 が 在控 になったと報告しています。エスケープが原因かどうかは確認されていないので、このプラグインは原因ではなく結果をチェックします。
anthropics/claude-code#83033 は両方の書き方を比べました。エスケープで書いた実行は 45 回すべてでハングルの一部(音節の約 3〜5%)が壊れ、UTF-8 で書くよう指示した実行はほとんど壊れませんでした。Claude Code はエスケープをそのままデコードするだけなので、間違ったコードポイントは直せません。この issue はモデルチームに渡されています。
この issue が修正済みとして閉じられれば、このプラグインは不要になります。そのときはセッション開始時にお知らせし、CI も毎日 issue の状態を確認しています。
動作
セッション開始時に SessionStart フックが Claude に指示を 1 行加えます。ツール呼び出しの非 ASCII 文字は \uXXXX エスケープではなく UTF-8 の文字そのままで書き、そのまま写すコードの中のエスケープだけは例外とする、という内容です。#83033 で効果が確認された回避策です。
ツール呼び出しの前に毎回 PreToolUse フックが入力のテキストを確認します。壊れて見える文字があれば呼び出しを一度止め、どの文字がどこにあるかを Claude に伝えます。同じ呼び出しを変えずにもう一度送れば通るので、意図したまれな語なら 1 往復増えるだけで作業は止まりません。
1 日に 1 回、セッション開始フックがバックグラウンドで GitHub に #83033 が修正済みとして閉じられたかを確認します。閉じられていれば、セッション開始時にプラグインを無効にしてよいという 1 行が表示されます。この通知と韓国語、日本語のチェックは /config で無効にできます。
チェックする内容
Claude Code はフックに渡す前にモデルの JSON をデコードするので、フックはエスケープそのものではなく、それが変わった結果だけを見ます。
- まれな漢字
- かなを含む文章で、JIS X 0208(Shift_JIS)の漢字 6,355 字にない漢字。#54051 の
諿、勭、簡体字の侧、亿を検出します。16 進数を 1 桁間違えると約 66% がこの外に出ます。かなを含まない文章は中国語かもしれないのでチェックしません。 - まれなハングル
- 韓国語の文章のほとんどを占める KS X 1001(EUC-KR)の 2,350 字にない音節。16 進数を 1 桁間違えると約 70% がこの外に出ます。#83033 の
릷、딅、잩を検出します。 - 片方だけのサロゲート
\uD83Aなどの半分だけの文字。API が 400 で拒否し、セッションが終わることがあります。U+FFFD- デコードに失敗した場所に残る置換文字。
\uXXXX- 質問、ToDo、MCP 呼び出しなどコード以外の場所に、文字ではなくテキストとして書かれたハングル、かな、漢字のエスケープ。
間違った文字がそれ自体よく使う文字だと検出できません。16 進数が別のよく使う音節に当たった場合(잡히지 が 잡힐지 に)や、鳴 が 鳥、再起動 が 在控 になった場合です。フックより前に Claude Code が拒否した呼び出しと、中国語の文章の間違った漢字も検出できません。
関連 issue
バッジは各 issue の現在の状態です。
原因
- #83033
Claude がツール呼び出しのパラメータの韓国語を
\uXXXXで書き、16 進数を間違える。このプラグインを作った理由。
同じ症状
- #80009
AskUserQuestion の入力の韓国語の音節が壊れる。セッションログで確認済み。
- #78996
長い韓国語のセッションでハングルが崩れる。
- #57981
AskUserQuestion で、間違っているが実在する音節がときどき出る。
- #53665
Opus 4.7 で tool_use の JSON パラメータの韓国語が壊れる。
- #82588
Opus 5 が間違ったハングルの音節を書く。
- #79339
エスケープの途中のグリッチで、ツール入力全体がパースできなくなる。
- #61670
片方だけの
\uD83Aと壊れた韓国語でセッションが終わる。- #69522
エスケープで書いた長いツール引数がパースに失敗する。
- #54051
Notion MCP ツールで書いた日本語に間違った漢字が混ざる。一部は簡体字。
- #59649
Opus 4.7 の AskUserQuestion に、形は似ているが間違った漢字が出る。
- #56003
AskUserQuestion に日本語が
\uXXXXのまま表示される。- #78568
繁体字中国語の出力に間違った文字が混ざる。
ツールが作る同じエスケープ
- #99361
エスケープの形で一致したあと、Edit が
new_stringの非 ASCII 文字をすべてエスケープで書く。- #72957
Write と Edit がファイル内容の
\uXXXXをデコードしてしまう。
フックから見えないもの
よくある質問
Claude が書く内容は変わりますか?
セッション開始時の指示を通してだけで、Claude が常に従うとは限りません。フックは呼び出しを書き換えません。通すか、一度止めて理由を伝えるだけです。
日本語や中国語を使っています。役に立ちますか?
日本語には効きます。指示、漢字のチェック、サロゲート・U+FFFD・テキストのエスケープのチェックがすべて適用されます。中国語には指示と後の 3 つのチェックだけが適用されます。中国語では決まった字の集合の外の漢字も普通に使われ、間違った字を区別できないためです。
まれな音節を意図して書いた場合は?
Claude が呼び出しを止めた理由を読み、同じ呼び出しを変えずにもう一度送れば、2 回目は通ります。頻繁に止まるなら /config で「Check Japanese kanji」か「Check Korean syllables」を無効にしてください。
どこかにデータを送りますか?
「Notify when fixed upstream」が有効なら、1 日 1 回 GitHub API に anthropics/claude-code#83033 の状態を問い合わせ、答えをプラグインのデータフォルダに保存します。セッションの内容は送りません。
どの OS で確認していますか?
Ubuntu、Windows、macOS で CI を実行し、毎日最新の Claude Code でも確認しています。フックには Node.js 18 以上が必要です。
無効にする、または削除するには?
無効にするには claude plugin disable utf8-guard、削除するには claude plugin uninstall utf8-guard を実行します。