Claude Media
Claude CodeのENOENT fchmodエラー — VM共有フォルダでEdit/Writeが失敗する原因

Claude CodeのENOENT fchmodエラー — VM共有フォルダでEdit/Writeが失敗する原因

VMの共有フォルダ上の既存ファイルだけEditとWriteがENOENT: fchmodで失敗する症状の原因です。新規作成は通る理由、確認用の短いスクリプト、使える回避策を示します。

既存ファイルだけ書き換えられない症状

VMwareなどの共有フォルダ(Windowsゲスト上でドライブ文字に割り当てたもの)でClaude Codeを動かすと、EditとWriteが次のエラーで止まることがあります。

Error: ENOENT: no such file or directory, fchmod

特徴は、失敗する対象が「すでに存在するファイル」に限られる点です。報告されている再現結果は次のとおりです。

操作ローカルのC:(NTFS)共有フォルダのドライブ
Writeで新規ファイルを作るローカルのC:(NTFS)成功共有フォルダのドライブ成功
Writeで既存ファイルを上書きするローカルのC:(NTFS)成功共有フォルダのドライブfchmodで失敗
Editで既存ファイルを変更するローカルのC:(NTFS)成功共有フォルダのドライブfchmodで失敗
Writeで作ったばかりのファイルをEditするローカルのC:(NTFS)成功共有フォルダのドライブfchmodで失敗

最後の行が重要です。ファイルの作られ方やセッションは関係ありません。「そのパスにファイルがもう在るか」だけが分かれ目になります。エラー文のENOENTは「ファイルが無い」と読めますが、実際にはファイルは存在します。後述するfchmodの失敗がこの名前で表に出ているだけです。

なぜfchmodで止まるのか

issueの報告者は、書き込みの手順を次のように推測しています。

  1. 一時ファイルに内容を書く
  2. 元のファイルのパーミッション(モードビット)を一時ファイルへ引き継ぐ
  3. 一時ファイルを元のパスへ改名して置き換える

新規作成には引き継ぐ権限が無いので、2が走りません。だから新規作成だけが通ります。既存ファイルでは2でfchmod()が呼ばれ、共有フォルダのファイルシステムドライバーがこの呼び出しを受け付けず、処理全体が中断します。

別の報告者は、もう少し具体的な切り分けを書いています。Windowsではfchmodの実体が、ファイル属性(読み取り専用フラグ)を書き換えるファイル情報の設定要求になります。VMwareのHGFS(ホストとゲストの共有フォルダ機構)は、ファイルの作成と書き込みの要求には応じますが、この属性の設定要求には応じない、という説明です。いずれも仮説の段階で、Anthropic側が原因を確定させたわけではありません。

仮説の細部はともかく、動作として確かなのは次の点です。

  • 内容の書き込みと改名そのものは共有フォルダ上でも成功する
  • 失敗するのは「モードビットの引き継ぎ」の1手順だけ
  • ローカルのNTFSでは同じ手順が通る

どのバージョンから起きるか

最初のissueでは、最後に動いたバージョンが2.1.179、症状が出たバージョンが2.1.198と書かれています。後から追加された報告では、症状は2.1.181から出るとされています。

2.1.181のchangelogには、次の修正が載っています。

Fixed Write/Edit producing 0-byte or truncated files on network drives and cloud-synced folders

ネットワークドライブやクラウド同期フォルダでファイルが0バイトになったり途切れたりする問題への修正です。報告者は、この修正に合わせて書き込み経路へfchmodが加わったのではないかと見ています。changelogの文面にはfchmodもVMの共有フォルダも出てこないため、この因果はあくまで報告者の推測です。

報告された環境は次のとおりです。

  • Windows 11 Enterprise LTSC 2024、Windows Server 2019
  • VMware HGFSの共有フォルダ(\\vmware-host\Shared Foldersをドライブ文字に割り当てたもの)
  • プラットフォームはAWS Bedrock、モデルはOpus

issueのタイトルと概要には、VirtualBoxのvboxsfも同じ型の共有フォルダとして挙げられています。ただし、検証した環境として明記されているのはVMwareの共有フォルダです。VirtualBoxで同じ症状が出るかは、報告の範囲では裏付けがありません。

issueのラベルにはregressionとplatform:windowsが付いています。報告者の一人は2.1.212でも再現し、別の報告者は2.1.282でも直っていないと書いています。issueはopenのままで、修正バージョンの記載はありません。

自分の環境で当たっているか確かめる

Claude Codeを使わずに、失敗する1手順だけを切り出して確かめられます。issueの報告者が示した最小再現を、確認用に整えたものです。共有フォルダ上のドライブへ移動してからNode.jsで実行します。

cd Y:\
node -e "const fs=require('fs');const d='./probe.txt',t='./probe.txt.tmp';fs.writeFileSync(d,'original\n');const st=fs.statSync(d);const fd=fs.openSync(t,'w');fs.writeSync(fd,'replacement\n');fs.fchmodSync(fd,st.mode);fs.closeSync(fd);fs.renameSync(t,d);console.log('ok')"

Y:\は共有フォルダのドライブ文字に読み替えてください。okと表示されれば、この経路のfchmodは通っています。次のようなエラーで止まるなら、Claude CodeのEditとWriteが失敗する条件と一致します。

Error: ENOENT: no such file or directory, fchmod

同じコマンドをC:\で実行してokになることも合わせて見ると、「共有フォルダだけの問題」だと切り分けられます。検証後はprobe.txtとprobe.txt.tmpが残っていないか確認して消します。

この確認で通るのにEditだけ失敗する場合は、別の原因を疑う段階です。ネットワーク共有が絡む別の症状は、Artifactが「Not published」になる原因の記事で扱っています。VM上でClaude Codeが固まる場合はHyper-Vで止まる原因の記事が参考になりますが、こちらとは原因が別です。

回避策

Claude Code側の修正が入るまでは、共有フォルダ上の既存ファイルを書き換えずに済む構成に寄せるしかありません。

ゲストのローカルディスクに作業コピーを置く

最も確実なのは、Claude Codeを動かす作業ディレクトリをローカルのNTFS(C:)に置く方法です。ローカルでは全操作が成功すると報告されています。共有フォルダは、成果物の受け渡し口に降格させます。

Gitを使っているなら、共有フォルダをリポジトリの置き場にせず、ローカルにcloneします。

git clone Y:\repos\app.git C:\work\app
cd C:\work\app
claude

編集が終わったらgit pushでホスト側へ返します。共有フォルダの上に置くのは、ベアリポジトリ(作業ツリーを持たないリポジトリ)だけにすると、Claude Codeが共有フォルダ上のファイルを直接書き換える場面がなくなります。

Gitを使わないプロジェクトでは、編集後にコピーを戻す手順になります。

robocopy C:\work\app Y:\app /E /XD .git node_modules

/MIRは付けていません。/MIRは転送元に無いファイルを転送先から削除するため、共有フォルダ側に独自のファイルがあると消えます。/Eだけなら上書きと追加にとどまります。

この方法の弱点は、ホスト側のIDEやビルドが共有フォルダ上のファイルを見ている構成では、コピーを戻すまで反映されないことです。Visual Studioをホストで動かし、ゲストから編集していたチームは、この往復が増えます。

ホスト側でClaude Codeを動かす

共有フォルダは、ホストから見ればただのローカルディスクです。ホストでClaude Codeを動かせるなら、そもそもこのエラーは起きません。issueには、プライバシーやセキュリティの規則でVMの外ではClaude Codeを使えない、というコメントも付いています。その場合はこの選択肢を取れず、上のローカルコピー方式が現実解になります。

2.1.179に固定する方法は行き止まりになりつつある

報告者の多くは、最後に動いた2.1.179へ戻して凌いでいました。固定の手順自体はClaude Codeバージョンの確認・固定・ダウングレード手順にあります。

ただし、この策には期限があります。issueへの9月25日のコメントによると、2.1.179ではOpus 5.5が「2.1.280以降が必要」というAPIエラー(400)で拒否されます。2.1.282でも症状が残っているので、「新しいモデルが使え、かつ共有フォルダ上の既存ファイルを編集できる」バージョンは見つかっていない、という状況です。モデルを諦めるかコピー方式に移るかの二択になるため、バージョン固定は一時しのぎにとどまります。

データは壊れないのか

失敗したEditやWriteは、対象ファイルを変更せずに終わると報告されています。切り詰めも起きず、.tmpファイルも残らないとのことです。失敗した操作で中身が壊れることはありません。

確認が要るのは、Claude Codeが失敗を見落として「編集した」つもりで次の手順へ進んでしまう場合です。そのときはgit diffなどで、変更が実際に入ったかを見ておきます。

修正案はどう提案されているか

issueでは、モードビットの引き継ぎを「できれば行う」処理にする案が出ています。内容の書き込みと改名が成功しているなら、モードの再設定に失敗してもやり直す必要はないという考え方です。

try {
  fs.fchmodSync(fd, st.mode);
} catch (e) {
  // 共有フォルダなどで未対応のときは続行する
  if (!["ENOENT", "ENOSYS", "EPERM", "EINVAL"].includes(e.code)) throw e;
}

同じ経路にfchownやutimesによる引き継ぎがあれば、同じ扱いにするよう添えられています。この案は報告者のもので、採用されるかは未定です。この形なら、2.1.181で入った切り詰め対策は残したまま、共有フォルダで落ちる1手順だけを緩められます。

修正の追跡

修正が入ったかは、issueのステータスと、Claude CodeのchangelogにあるWriteやEditに関する項目で見分けられます。更新後に前節のスクリプトを共有フォルダ上で再実行し、okになれば、少なくともこの1手順は通ります。

よくある質問

chmodで権限を変えれば直りますか

issueには、そうした対処の報告はありません。失敗するのはファイルの権限の中身ではなく、共有フォルダのドライバーがfchmod相当の呼び出し自体を処理できない点だと説明されています。

SMBやネットワークドライブでも同じ症状になりますか

報告で検証されているのはVMの共有フォルダです。修正案のコメントには「一部のSMB」も同種の制限を持つ例として挙がっていますが、検証結果としては示されていません。手元のドライブで前節のスクリプトを流すのが確実です。

参照した一次ソース

この記事の記述は、次の一次ソースと照合しています。更新時に参照先が変わった場合は一覧も更新します。

  1. github.com/anthropics/claude-code/issues/73386
  2. code.claude.com/docs/en/changelog
この記事を共有:XはてブLinkedIn