Claude Codeがスマート引用符を壊す問題と回避策
Claude CodeのEdit/Writeツールがスマート引用符やアポストロフィを直線の記号に書き換える既知の不具合と、公式修正の範囲、実務で使える回避策をまとめます。
Claude Codeがスマート引用符を書き換えるとは
Claude Codeのスマート引用符書き換え問題とは、EditツールやWriteツールでファイルを編集する際に、正しく入力されたUnicodeの曲線引用符(’“”)やアポストロフィを、ASCIIの直線引用符(' ")へ無断で変換してしまう既知の不具合です。GitHub Issue #1599として2025年6月4日に登録され、2026年6月17日に最後のコメントが付いた時点でもクローズされていません。2026年2月18日のv2.1.47でEditツールの一部の症状は修正されましたが、同じ現象を別の形で報告するコメントはその後も続いています。
最初の報告は、ユーザーがコード中に I’m という曲線アポストロフィ付きの文字列を書いていたところ、無関係な箇所を編集させただけで I'm に書き換わったというものでした。CLAUDE.mdに逆の指示(正しい引用符を使ってほしい)を書いても、Claudeは自分がルールに従えていないことを認識しながら、修正しようとすると「old_stringとnew_stringが完全に同じです」というエラーを繰り返すだけで直せませんでした。指示が効かないタイプの不具合である点が、この問題を厄介にしています。
書き換えは偶然ではなく正規化の副作用
この書き換えは、モデルの打ち間違いというより、Write/Editツールが書き込む前に行う正規化として報告されています。しかも、その正規化は別の不具合への対策として入ったものだという説明があります。
Issue #31482(後述の/curlyの提案)は、正規化の目的を「モデルがコード中に曲線引用符を出力して、パーサーを壊すことがある」という実在の不具合への対策だと説明しています。同じ提案は、その副作用として、文書・Markdown・多言語の文章に含まれる正当な曲線引用符まで壊れると書いています。壊れる向きは文章の中身かコードの区切りかで逆になり、どちらも静かに起きます。
同じ正規化で壊れる2つの向き
直線化されて壊れる
曲線アポストロフィ(U+2019)や曲線二重引用符が直線に変わります。Markdownや翻訳ファイルでは表記が崩れ、Perlでは文字列の区切りが壊れて構文エラーになります。Issue #1599の中心はこちらです。
曲線化されて壊れる
直線の " が閉じ二重引用符(U+201D)に変わります。Issue #29786では、HTMLの class=”stat-note” のようになり、ブラウザーがU+201Dを属性の区切りと認識せず、CSSセレクターが効かなくなりました。
Issue #29786の報告者はブルガリア語の文字を含むHTMLを編集していて、似た形の31個の p 要素のうち6個の class 属性で置換が起きたと書いています。エラーは出ず、気づく手がかりは崩れたレイアウトだけでした。
Edit側の挙動はIssue #26141に具体的に書かれています。old_stringは正規化を通して一致するため、直線引用符で書いた置換でも編集自体は成功します。結果として、編集した行だけが直線引用符になり、触れていない行は曲線引用符のままという、混在状態のファイルになります。\uXXXX と書いたnew_stringは、エスケープとして解釈されずに文字列そのものが書き込まれたとも報告されています。
なぜ意図した文字が書き換わるのか
Issue #1599には、2025年8月に自分のコードの正規表現で同じ現象に当たった報告者がいます。この報告者は、Claudeモデル自体の判断ミスというより「スタック内の別の処理・フィルタ層で発生している」と推測しています。同じ編集をGemini CLIにさせたところ、曲線アポストロフィはそのまま残ったという画像も添えられていて、Claude Code側の処理に原因がある可能性を示す材料になっています。
厄介なのは、Claude自身が正しい文字コードを認識していながら、実際の出力ではそれを再現できないという点です。あるユーザーが「開き引用符と閉じ引用符(いわゆるcurly quote)を使ってHello worldを出力して」と指示したところ、Claudeは「開き引用符はU+201C、閉じ引用符はU+201D」だと正しく説明しながら、実際の出力はASCIIの直線引用符でした。このバグ報告を読ませると、Claude Code自身が次の趣旨のコメントを返しています。「処理パイプラインのどこかでUnicodeのタイポグラフィ文字がASCII相当に正規化されている」。そして「正規化された後の状態しか自分では見えていないので、自分の出力が影響を受けていることに気づけない」。
CLAUDE.mdへの指示が効かないのも同じ構造で、モデルが従うべきルールを認識できても、書き換えが起きる層まで指示が届いていないと考えられます。同様の乖離はモデルが更新されたあとも報告されています。KingSupernova31は、Opus 4.6の時点でも、実際には直線引用符を出力していながら「曲線引用符を使っている」と誤って言い切る挙動が残っていたと書いています。
IDE拡張の自動編集がどこまで許可されるかでは、protected pathsやVS Code Restricted Modeなど、自動編集に対する複数の防御層が扱われています。スマート引用符の書き換えは、そうした防御層とは別に、編集内容そのものが処理の過程で変質するという種類の問題です。ArtKoKoは、文章中の曲線引用符と、コードの区切りとして使われる直線引用符を、意味を理解せずに機械的に区別する方法は無いと分析しています。そのためフックによる後処理だけでは確実な修正が難しいとしています。
影響を受けるケースとその実害
もっとも実害が大きいのは、直線引用符が構文上の意味を持つプログラミング言語です。Perlで書かれたコードでは、アポストロフィ付きの文字列がEditツールの書き換えによって構文エラーに変わります。
# 書き換え前(正しく動く)
$text = "Nom d’hôte"; # U+2019のアポストロフィ
# Editツール適用後(構文エラー)
$text = "Nom d'hôte"; # U+0027が文字列の区切りとして解釈されてしまうこの報告をしたユーザーは、1つのファイルだけで502行が影響を受けたとしています。Perl以外にも、次のような環境・ケースが報告されています。
| 環境・言語 | 報告された影響 |
|---|---|
| Perl(Linux Fedora 42) | 報告された影響文字列リテラルの区切りが崩れて構文エラーになる |
| ポルトガル語のUI文字列(Windows 11+WSL2、Claude Code CLI v2.0.55、Opus 4.5) | 報告された影響ç・ã・é・ôなどのアクセント記号がASCII相当の文字に置き換わる、または欠落する |
| ローカライズファイル全般 | 報告された影響多言語のUI文字列や翻訳ファイルで、引用符・アポストロフィが直線化する |
| Claude.aiのチャット画面 | 報告された影響Claude Code以外でも、モデル出力そのものが直線引用符になるとの報告がある |
| AWS Bedrock経由 | 報告された影響Bedrockを使っていて同じ問題に当たったという報告もある |
ArtKoKoは、この問題がフランス語やドイツ語のように、タイポグラフィ上の正しい引用符を使う言語のプロジェクトで特に表面化すると指摘しています。英語以外の言語を扱うコードベースや翻訳ファイルほど、曲線引用符やアクセント記号に依存した文字列が多いためです。
v2.1.47で直った範囲とまだ残っている範囲
2026年2月18日公開のv2.1.47では、公式changelogに次の修正が記載されています。
Fixed Edit tool silently corrupting Unicode curly quotes (“” ‘’) by replacing them with straight quotes when making edits (anthropics/claude-code#26141)
これはEditツールが “” ‘’ の4種類の文字を直線引用符へ書き換えてしまう不具合を対象にした修正です。changelogで引用符の書き換えに触れているEditツールの項目は、この1行です。
Issue #1599のスレッドでは、報告がこの修正の前後で途切れず続いています。ArtKoKoは2026年3月のコメントで、同じ現象が#8234・#14355・#15920・#26141・#29786と、少なくとも5件の重複Issueとして個別に登録されてきたと指摘しています。
報告と修正の流れ
- 2025年6月Issue #1599が登録される
最初の報告時点のバージョンはv1.0.11(macOS)です。その後、Linux・Windows+WSL2の報告が続きました。
- 2026年2月6日v2.1.31でも起きているとの報告
ローカライズファイルの編集でエラーに当たったというコメントが付きました。
- 2026年2月18日v2.1.47でEditツールの直線化を修正
Editツール内の書き換えが修正されました。
- 2026年4月17日Opus 4.7で改善したとの報告
回避策のプレースホルダー方式を外せたというコメントが付き、別のユーザーも同じ結果を報告しました。
- 2026年5月〜6月Opus 4.7でも直っていないとの報告
Claude.aiのチャットやAWS Bedrockでも起きるというコメントが続きました。
関連Issueの状態を並べると、公式の対応が止まっている場所がわかります。
| Issue | 内容 | 状態 |
|---|---|---|
| #1599 | 内容本件の元Issue | 状態オープン |
| #26141 | 内容Editツールが曲線引用符を直線化 | 状態2026年2月16日にcompletedでクローズ |
| #1986 | 内容曲線引用符と直線引用符を区別できない | 状態2026年1月15日にnot plannedでクローズ |
| #29786 | 内容HTML属性に曲線引用符が混入 | 状態2026年4月4日にnot plannedでクローズ |
| #31482 | 内容/curlyオプションの機能要望 | 状態2026年4月4日にnot plannedでクローズ |
v2.1.47以降の報告は割れています。Opus 4.7で直ったという報告がある一方で、Opus 4.7でも直らないという報告が続いています。
今すぐ試せる回避策
完全な修正ではありませんが、実務で試されている回避策がいくつか報告されています。どれを使うかは、壊したくない文字がコードの中にあるか、文章の中にあるかで分かれます。
コード中の文字列にはエスケープを使う
ソースコード中で ’ のようなリテラル文字の代わりに、言語のエスケープ表記を使う方法です。JavaScriptやPythonなら \u2019 と書きます。Issue #1599のコメントで別の報告者が提案したのはこのUnicodeエスケープの形で、Perlなら \x{2019} でも書けます。提案者は「まだ試していない」と書いているため、効果は自分のリポジトリで試す必要があります。ソースの可読性は下がりますが、リテラルの曲線引用符がファイルに残らないので、正規化の対象になりません。
Markdownや翻訳ファイルのようにエスケープが解釈されない文章では、この手は使えません。Issue #26141では、\uXXXX と書いてもそのままの文字列が書き込まれたと報告されています。
文章ファイルの置換はEditツールを経由しない
perl -i -pe はファイルを直接書き換えるので、Editツールの正規化を通りません。Issue #1599では、Perlの報告者がこの方法でUTF-8が保たれたと書いています。
perl -i -pe "s/old/new/g" file.plプレースホルダーで退避する
コミュニティが公開しているワークアラウンドの一つは、プレースホルダーを使う方法です(Issue #1986で共有されています)。編集前にスマート引用符を一時的な文字列へ置換し、Editツールの処理が終わったあとにperlやsedで元の文字へ戻します。#1986そのものは2026年1月15日にクローズされ、その後ロックされています。
ArtKoKoが提案した/curlyは、コードの区切りとして使われる直線引用符と、文字列の中身としての曲線引用符を区別して扱うオプションです。迷ったときにコード側(直線)に倒すsafeモードと、文章側(曲線)に倒すlazyモードの2種類が想定されていました。このIssue #31482は2026年4月4日にnot plannedでクローズされ、機能としては入っていません。
コミット前に差分で検出する
書き換えは通知なく起きるため、実質的な最後の安全網はコミット前の差分です。Claude Codeのcheckpoint機能はEditツールが加えた変更そのものは記録しますが、その変更が意図した内容かどうかまでは判定しません。差分の削除側(-の行)に曲線引用符が含まれていないかを機械的に拾えば、目視より見落としが減ります。
編集後に書き換えを検出する流れ
- 1
差分の削除行から曲線引用符を拾う
-で始まる行のうち、U+2018・U+2019・U+201C・U+201Dを含む行だけを表示します。意図した編集で消した行も出るので、候補の一覧として使います。 - 2
該当行が直線引用符に置き換わっていないか見る
同じ行が
+側で直線の'や"になっていれば、正規化による書き換えです。 - 3
戻すか、Editツールを使わずに置換し直す
文章ファイルなら、上のperlによる置換で元の文字に戻せます。
手順1のコマンドの出力例は次のとおりです。
git diff -U0 | perl -CSD -ne 'print "$.: $_" if /^-.*\x{2019}/'6: -$text = "Nom d’hôte"行頭の数字は差分内の行番号です。
逆方向の破損も報告されている
Issue #29786のような曲線化は2026年3月から報告されていて、2026年4月18日のコメントでも、直線引用符のはずの場所に曲線引用符が混入して構文エラーになったという報告が出ています。あるユーザーは丸一日デバッグに費やしたあとで、Claude自身に「曲線の引用符やアポストロフィを本当に必要とするプログラミング言語はあるか」と尋ねました。Claudeの回答は「ない」でした。JSONは仕様上U+0022の直線引用符のみ、シェルは曲線引用符で即座にパースエラーになる、と挙げています(Claudeの回答であり、Anthropicが検証した仕様ではありません)。
曲線引用符が正当なのは、画面に表示される文字列の中身としてです。コードの区切りに混ざった曲線引用符は、次のコマンドでソースファイルから拾えます。
perl -CSD -ne 'print "$.: $_" if /[\x{2018}\x{2019}\x{201C}\x{201D}]/' index.html1: <p class=”stat-note”>a</p>文章中の正当な曲線引用符も同じ行として出るので、HTMLやJSONのようにコードの区切りに曲線引用符が入らないはずのファイルで使うのが向いています。
まとめ
Opus 4.7で直ったという報告と直らないという報告が割れているので、モデルを替えた後も差分の検出を続ける選択肢があります。
Perlのようにコードの区切りが崩れるファイルは構文エラーで気づけますが、Markdownや翻訳ファイルは静かに崩れます。後者を先に差分で見ておくと、書き換えを早く拾えます。
参照した一次ソース
この記事の記述は、次の一次ソースと照合しています。更新時に参照先が変わった場合は一覧も更新します。