Claude Code が作る削除できない nul ファイルの原因と対処法
Claude Code を Windows で使っていると、いつの間にかプロジェクトのフォルダに nul という名前のファイルが増えていて、右クリックで削除しようとしても「ファイルが見つかりません」と拒否される——そんな不可解な現象に遭遇した人は少なくありません。しかもコマンドを叩くたびに再発するため、原因が分からないままイライラする声が多いテーマです。本記事では、この nul ファイルがなぜ生まれるのかという仕組みから、確実に削除する方法、そして再発を止める設定までを順を追って整理します。
nul は Windows の予約デバイス名を狙ったリダイレクトが実ファイルとして書き出されたもので、通常操作では消せない。\\?\ を付けた UNC パスで del すれば削除でき、フックや Windows ネイティブ設定で再発も防げるとわかる。
Contents (11)
nul ファイルとは何か — Windows の予約デバイス名
Windows には、ファイルとして使えない「予約デバイス名」が存在します。NUL はその代表で、CON(コンソール)、PRN(プリンタ)、AUX などと並んで、OS が仮想デバイスとして特別扱いする名前です。
Unix 系の /dev/null に相当し、command > NUL と書けば出力を捨てる「ゴミ箱」として機能します。本来この NUL は物理的なファイルではなく、OS がその場で処理する仮想的な受け皿です。
ところが何らかの理由でこの名前が実体を持つファイルとしてディスクに書き込まれてしまうと、途端に厄介な存在になります。OS は nul という名前を「デバイス名」として解釈するため、エクスプローラーからの削除も、通常の del nul コマンドも「アクセスできない」「見つからない」と弾かれてしまうのです。
出典: Microsoft Learn - Naming Files, Paths, and Namespaces
なぜ Claude Code は nul ファイルを作るのか
Claude Code が実行するコマンドの中には、不要な出力を捨てるために 2> nul や > nul といったリダイレクトを含むものがあります。これ自体は Windows の cmd では正しく仮想デバイスに向かいます。
問題が起きるのは、Unix 系を前提に組み立てられたコマンドが、Windows のシェル環境で意図せず実ファイルを生成するケースです。本来 Unix なら /dev/null と書くべきところ、あるいは Git Bash・WSL とネイティブシェルが混在する環境で nul へのリダイレクトが「デバイスへの書き込み」ではなく「nul という名前のファイル作成」として解釈されてしまいます。
GitHub の Issue でも複数の環境(Windows Server 2019、PowerShell / cmd 併用)で報告されており、共通するのは次の流れです。
- Windows 上で Claude Code を起動する
- ディレクトリ内で何らかのコマンド操作が走る
- 出力リダイレクトが実ファイル化し、作業ディレクトリに
nulが出現する
厄介なのは、ツールが呼び出されるたびに再生成される点です。一度消してもまた現れるため、根本的には後述する再発防止策とセットで対応する必要があります。
出典: anthropics/claude-code Issue #15398 - Windows: Creates undeletable nul files in working directory
削除できない理由 — 標準の削除が弾かれる仕組み
nul ファイルが消せないのは、Windows のファイル API が名前解決の段階で「これはデバイス名だ」と判断し、実ファイルへのアクセスに到達する前に処理を横取りしてしまうからです。
- エクスプローラーでの削除 → 「項目が見つかりませんでした」
del nul→ デバイスとして解釈され失敗rmdirや名前変更 → 同様に予約名チェックで拒否
つまり、通常の削除経路がすべて「予約名の保護機構」に阻まれます。この保護を回避しない限り、ファイルは残り続けます。次のセクションで、その回避方法を具体的に示します。
nul ファイルを確実に削除する方法
手順1: UNC パス(\?\ プレフィックス)で削除する
最も確実なのは、\\?\ という特殊なプレフィックスを付けて絶対パスを指定する方法です。この \\?\ は Windows の名前解決を無効化し、予約名チェックをバイパスして実ファイルへ直接アクセスさせる「魔法の鍵」です。
コマンドプロンプトの場合:
del "\\?\D:\path\to\project\nul"
D:\path\to\project の部分は、nul ファイルがある実際のフォルダの絶対パスに置き換えてください。
手順2: PowerShell で削除する
PowerShell を使う場合は -LiteralPath を指定して、パスをそのまま解釈させます。
Remove-Item -LiteralPath "\\?\D:\path\to\project\nul" -Force
-LiteralPath はワイルドカードやエスケープ処理を無効化するため、\\?\ を含む特殊なパスをそのまま渡せます。
手順3: Python から Win32 API を直接叩く
スクリプトで自動化したい場合は、DeleteFileW を直接呼び出す方法もあります。
import ctypes
from ctypes import wintypes
import os
kernel32 = ctypes.WinDLL('kernel32', use_last_error=True)
DeleteFileW = kernel32.DeleteFileW
DeleteFileW.argtypes = [wintypes.LPCWSTR]
DeleteFileW.restype = wintypes.BOOL
path = '\\\\?\\' + os.path.abspath('nul')
DeleteFileW(path)
いずれの方法でも共通するのは、\\?\ プレフィックスによって予約名の保護を無効化している点です。この 1 点さえ押さえれば、nul だけでなく con や prn といった他の予約名ファイルも同じ手順で削除できます。
出典: DEV Community - How to Delete the Un-deletable "nul" File Created by Claude Console on Windows 11
再発を防ぐ設定 — フックで自動削除する
削除できても、コマンドのたびに nul が再生成されては意味がありません。根本的には、Claude Code のフック機能を使い、ツール実行のたびに自動で nul を掃除する仕組みを組むのが現実的です。
.claude/settings.local.json に PostToolUse フックを追加し、各ツール実行後に nul を削除するコマンドを走らせます。イメージとしては、ツール実行後に del "\\?\%CD%\nul" のような削除コマンドを毎回発火させ、nul が現れても即座に消える状態を保つ設計です。
フックはツールの実行結果には干渉せず、あくまで後片付けとして動くため、ワークフローを壊さずに再発を封じられます。
環境側で根本を断つ — シェルとパスの見直し
自動削除は対症療法であり、そもそも nul が生成されない環境を整えるのが理想です。以下の観点を確認するとよいでしょう。
- ネイティブシェルの統一: Git Bash・WSL・cmd・PowerShell が混在していると、リダイレクトの解釈が環境依存でぶれます。Claude Code が使うシェルを一つに揃えることで、
nulと/dev/nullの取り違えを減らせます。 - 最新版へのアップデート: この問題は継続的に報告・修正が進んでいるため、Claude Code を最新バージョンに保つことで、内部的なリダイレクト処理の改善を取り込めます。
- 一時ディレクトリの確認: 関連する Issue では一時ディレクトリの後始末が絡むケースも報告されています。作業ディレクトリを定期的に点検し、
nul以外の残骸がないかも合わせて確認しておくと安心です。
出典: anthropics/claude-code Issue #17783 - Windows: Temp directories and nul files not cleaned up
よくある誤解と注意点
nul ファイルを扱う際に、いくつか混同しやすいポイントがあります。
nulは「壊れたファイル」ではない: 中身が空でサイズ 0 に見えても、実体は予約名と衝突した通常ファイルです。ウイルスやシステム破損ではないので、慌てて OS を再インストールする必要はありません。\\?\を付け忘れると必ず失敗する: パスの絶対指定を忘れたり、プレフィックスを省いたりすると、また予約名チェックに弾かれます。エラーが出たらまずプレフィックスの有無を疑いましょう。- バージョン管理に混入させない:
nulが Git のワーキングツリーに紛れ込むと、他の OS のメンバーがチェックアウトできなくなる恐れがあります。.gitignoreに加えるか、コミット前に必ず削除してください。
まとめ
Windows で Claude Code を使うと現れる削除できない nul ファイルは、NUL という予約デバイス名を狙ったリダイレクトが実ファイルとして書き出されてしまう現象です。仕組みさえ理解すれば対処は明快で、削除には \\?\ プレフィックスを付けた UNC パス指定、再発防止にはフックによる自動削除やシェル環境の統一が有効です。同じ手法は con や prn など他の予約名ファイルにも応用できます。原因不明のまま消せずに悩んでいたなら、本記事の手順で一度きれいに片付けてしまいましょう。