Claude Media
「Read deny rule」エラーの対処 — Claude Code

「Read deny rule」エラーの対処 — Claude Code

Claude CodeのEdit・Writeが「Read deny rule」で止まる原因は、Readのdenyルールが同じパスのEditとWriteも塞ぐ仕様だからです。NotebookEditが対象外になる点も扱います。

.envsecrets/Readのdenyルールで守っているプロジェクトがあります。そのファイルをClaude Codeに編集させようとすると「File is covered by a Read deny rule」で止まります。原因は単純です。Readのdenyルールは、読み取りだけでなく同じパスのEditとWriteも一緒に塞ぐ仕様になっているためです。設定ミスではなく、意図された安全策として働いています。

File is covered by a Read deny ruleとは何のエラーか

表示される文言は次のとおりです。

File is covered by a Read deny rule in your permission settings and cannot be edited.

Writeツールが拒否されたときは文末だけ変わり、and cannot be writtenになります。EditツールとWriteツールは、どちらも書き込んだ内容をClaude自身が読み返せる必要があります。読み取りそのものをReadのdenyルールで塞いでいる以上、書き込みだけを許すと「書いたのに読めない」という矛盾した状態になります。そのためClaude Codeは、ファイルへ一切アクセスする前に呼び出しごと拒否します。新規ファイルの作成であっても、そのパスがReadのdenyルールに一致すれば同じように弾かれます。

なぜReadのルール1つでEditとWriteの両方が止まるのか

多くの人が最初につまずくのはここです。「読み取りを禁止しただけなのに、なぜ編集まで止まるのか」という疑問は自然です。Claude Codeのパーミッションチェックは、ファイルツールとパスの対応がEdit(path)Read(path)の2種類だけという設計になっています。WriteNotebookEditMultiEdit向けにパスルールを書いても、Claude Codeはルールとして受理はするものの実際には参照しません。書くべきは常にEdit(docs/**)であり、Write(docs/**)ではないという点が、このエラーの背景にある設計です。

つまりReadのdenyルールは「読み取り拒否」と「編集拒否」の二役を1つのルールで兼ねています。ルールを2つに分けて書く必要はなく、Read(./secrets/**)と書いた時点で、そのパスへのEdit・Writeも自動的に塞がれます。

バージョンによる挙動の違い

このガードは段階的に強化されてきました。現在の挙動を前提に設定を組んでいると、古いバージョンでは想定どおりに動かないことがあります。

バージョンEditの扱いWriteの扱い
v2.1.208より前Editの扱いReadのdenyルールでは止まらない(専用のEditdenyルールが必要)Writeの扱い止まらない
v2.1.208以降Editの扱いReadのdenyルールで止まるWriteの扱い止まらない
v2.1.228以降Editの扱いReadのdenyルールで止まるWriteの扱いReadのdenyルールで止まる

古いバージョンで「Readにdenyを書いたのにEditやWriteが通ってしまう」場合、まず疑うべきは設定ではなくバージョンです。claude updateで最新化するだけで、追加設定なしにガードが効くようになります。

NotebookEditだけは対象外

ReadのdenyルールがEdit・Writeを塞ぐ一方で、NotebookEditツールはこのガードの対象外です。Jupyter Notebook(.ipynb)を編集専用ツールで直接書き換える経路は、Readのdenyルールだけでは止まりません。ノートブックを含むディレクトリを本当に触らせたくない場合は、Readのdenyルールに加えてEditのdenyルールも同じパスへ足す必要があります。

対処法

状況によって、取るべき対応は2つに分かれます。

  • Claudeに編集させたい場合: /permissionsまたはsettings.jsonpermissions.denyから、該当パスのReadルールを削除するか、範囲を狭める。プロジェクト全体を覆うRead(./secrets/**)のようなワイルドカードが原因になっていることが多く、必要な範囲だけに絞り込めば編集が通るようになります
  • ファイルには一切触らせたくない場合: Readのdenyルールはそのまま残し、Editのdenyルールを同じパスに追加してNotebookEditの経路も塞ぐ

機密ファイルを守る設定は、公式ドキュメントが挙げているこの形が土台になります。

{
  "permissions": {
    "deny": [
      "Read(./.env)",
      "Read(./.env.*)",
      "Read(./secrets/**)",
      "Read(./config/credentials.json)"
    ]
  }
}

このパターンで.envsecrets/配下を保護すると、ファイル探索・検索結果からの除外、読み取り拒否、EditとWriteの拒否までを1つの設定でまとめて実現できます。

allowルールを書いても止まる理由

Edit: allowのような許可ルールを別途書いていても、このエラーは解消しません。Claude Codeのルール評価順序はdeny → ask → allowの順で固定されており、最初に一致したルールが結果を決めます。Bash(aws *)のような広いdenyルールは、より具体的なBash(aws s3 ls)のallowルールを上書きします。同じ関係が、ReadのdenyルールとEditのallowルールの間にも成り立ちます。denyルールは許可の例外を持てないため、Editを通したいなら許可を足すのではなく、denyルール自体を削るか狭める以外に道はありません。

WriteGlobにパスルールを書いてしまう間違い

パーミッション設定でありがちな誤りが、Write(path)Glob(path)にルールを直接書くパターンです。Claude Codeはこれらのルールを設定ファイルとしては受理しますが、ファイルアクセスの判定時には一切参照しません。起動時に警告が出るため気づく機会はありますが、警告を見落としたまま「ルールを書いたのに効かない」と誤解しやすいポイントです。対応表は次のとおりです。

書いてしまいがちなルール実際に書くべきルール
Write(docs/**)実際に書くべきルールEdit(docs/**)
NotebookEdit(docs/**)実際に書くべきルールEdit(docs/**)
MultiEdit(docs/**)(レガシー)実際に書くべきルールEdit(docs/**)
Glob(docs/**)実際に書くべきルールRead(docs/**)

例外は--allowedTools経由で渡すGlobルールのみで、これだけはコマンドライン引数として機能します。設定ファイル(settings.json)に書くGlobルールは無効なままです。

ignorePatterns設定からの移行

機密ファイル除外の設定は、以前はignorePatternsというキーで書かれていました。現在のpermissions.denyはこの設定を置き換えたもので、書き方だけでなく効果範囲も広がっています。permissions.denyReadルールを書くと、ファイル探索・検索結果からの除外に加えて読み取り拒否も実現します。さらに本記事のテーマであるEdit・Writeの拒否まで、1つの設定で一括して実現できます。古いignorePatternsをそのまま使っているプロジェクトを引き継いだ場合は、permissions.denyへの書き換えを検討する価値があります。

Bash経由のファイルアクセスとの違い

ReadEditのdenyルールは、Claude Codeの組み込みファイルツールに適用されます。加えて、Bashで実行されるcatheadtailsedのような「Claude Codeが認識しているファイルコマンド」にも適用されます。ただし、Pythonスクリプトやnode.jsのプログラムが内部でファイルを開くような、任意のサブプロセス経由のアクセスまでは対象外です。OSレベルで全プロセスからのアクセスを止めたい場合は、denyルールではなくサンドボックスの設定が必要になります。

使い分け早見表

やりたいこと設定効果
Claudeに読ませない設定Read(path)のみ効果読み取り・Edit・Write(v2.1.228以降)を拒否。NotebookEditは通る
Claudeに一切触らせない設定Read(path) + Edit(path)効果読み取り・Edit・Write・NotebookEditすべてを拒否
特定パスだけ範囲を狭める設定Read(./secrets/**)をより具体的なパスへ書き換え効果意図しない広範囲ブロックを避けられる
OSレベルで完全遮断設定サンドボックス設定効果任意のサブプロセス経由のアクセスも遮断

よくある質問

.gitignoreに書いたファイルは自動的に保護されますか

されません。.gitignoreはGitの追跡対象外を決めるだけで、Claude Codeのパーミッションとは無関係です。機密ファイルを守るにはpermissions.denyReadのルールを明示的に書く必要があります。

既存ファイルの中身を書き換えず、末尾に追記だけしたい場合も止まりますか

止まります。Editツール・Writeツールは操作の種類にかかわらず、対象パスがReadのdenyルールに一致した時点でファイルへのアクセス自体を拒否します。追記か上書きかは判定に関係しません。

モノレポの一部のパッケージだけを保護できますか

できます。Readのdenyルールはグロブパターンを受け付けます。Read(packages/billing/**)のように特定のパッケージだけを指定すれば、他のパッケージには影響を与えずに保護できます。モノレポ全体に広いパターンをかけてしまうと、意図しないパッケージまでEditが止まってしまうため、保護したい範囲をパッケージ単位まで具体的に絞り込むのが安全です。

Readのdenyルールをユーザー設定(~/.claude/settings.json)に書いても効きますか

効きますが、パスの書き方に注意が必要です。ユーザー設定側のRead(/secrets/**)~/.claude/secrets/**を指し、プロジェクト内のsecretsディレクトリは対象になりません。プロジェクトをまたいで効かせたいなら、//から始まる絶対パスか~/から始まるホーム相対パスで書きます。

symlink経由でファイルにアクセスされた場合はどうなりますか

denyルールはsymlink自体とその参照先の両方をチェックします。参照先が別のdenyルールに一致すれば、symlink側が許可パスに含まれていてもブロックされます。allowルールより厳格に働く点が非対称です。

PreToolUseフックで同じことはできませんか

できますが、性質が違います。PreToolUseフックはツール呼び出しごとに任意のスクリプトを走らせて動的に許可・拒否を判定する仕組みで、条件分岐や外部連携を組み込めます。一方Readのdenyルールは、パスパターンに対して静的に決まる単純な拒否です。CI設定ファイルや.git配下のような「常に触らせたくない」パスにはdenyルールで十分で、状況によって判断を変えたい場合だけフックを組み合わせます。なお、フックが"allow"を返しても、一致するdenyルールがあれば拒否が優先される点は共通しています。

まとめ

「File is covered by a Read deny rule」は、ReadのdenyルールがEditとWriteの両方を道連れに塞ぐ仕様上のエラーです。読み取り拒否のつもりで書いたルールが編集まで止めてしまう挙動を「不便」と感じるか「意図どおりの安全策」と捉えるかで、対応の方向は変わります。編集させたいならReadルールの範囲を狭め、逆に一切触らせたくないならEditルールを追加してNotebookEditの抜け道もふさぎます。v2.1.208未満やv2.1.228未満のバージョンでは挙動が異なるため、設定を見直す前にまずバージョンを確認しておくと切り分けが早くなります。パーミッション設計全体を見直すならClaude Codeセキュリティ・権限ガイドが参考になります。settings.jsonの書式を確認するならClaude Code settings.json完全ガイドも役立ちます。

この記事を共有:XはてブLinkedIn