◉CLAUDE LABEN
●2.1.302 — fork サブエージェントが claude -p・Agent SDK・デスクトップで既定オンになりました。無効化は CLAUDE_CODE_FORK_SUBAGENT=0(10/16)●2.1.299 — 200K トークン超で約54分放置した会話はアイドル圧縮。MCP の許可ルールは名指ししたサーバーだけに一致します●SONNET 4.5 — Claude API での提供終了は 11/30、残り43日。移行先は Sonnet 5.5●WINDOWS — 日本語の環境でだけフックが黙って壊れる報告があり、文字コードの確認が呼びかけられています●FAST MODE — Opus 5.5 の Fast mode がリサーチプレビューを終え、ベータヘッダーが不要になりました(10/15)●NEW — Cowork に渡したフォルダの先頭に、十行の約束ファイルを置いてみました●2.1.302 — fork サブエージェントが claude -p・Agent SDK・デスクトップで既定オンになりました。無効化は CLAUDE_CODE_FORK_SUBAGENT=0(10/16)●2.1.299 — 200K トークン超で約54分放置した会話はアイドル圧縮。MCP の許可ルールは名指ししたサーバーだけに一致します●SONNET 4.5 — Claude API での提供終了は 11/30、残り43日。移行先は Sonnet 5.5●WINDOWS — 日本語の環境でだけフックが黙って壊れる報告があり、文字コードの確認が呼びかけられています●FAST MODE — Opus 5.5 の Fast mode がリサーチプレビューを終え、ベータヘッダーが不要になりました(10/15)●NEW — Cowork に渡したフォルダの先頭に、十行の約束ファイルを置いてみました
記事一覧/Claude.ai
◉ Claude.ai/2026-10-19中級

「ファイルを作成しました」と返ってきたのに、フォルダには何も無かった — 成功応答の後ろに置く読み戻し検証

ファイル作成が成功と返るのに実体が無いとき、原因を切り分ける順番と、書き込みの直後に読み戻して確かめる最小のスクリプトを整理します。

Claude52MCP56ファイル操作トラブルシューティング55検証4クラウド同期

夕方、書き出したばかりの設定ファイルを開こうとして、手が止まりました。Claude の返事には「ファイルを作成しました」とあります。ところがフォルダを見ても、ターミナルで ls を打っても、そのファイルはどこにもありません。

その日は、個人開発している壁紙アプリのストア用メタデータを整える作業の途中でした。私自身、Claude に「このフォルダに JSON を書き出して」と頼むのは日常の手順になっています。

エラーは一行も出ていません。だからこそ、胃のあたりが少し冷たくなりました。失敗したと分かっていれば、やり直せば済みます。厄介なのは、成功したと信じたまま次の工程へ進んでしまうことのほうです。

「作成しました」の応答と実体がずれたときの切り分けの順番と、書き込みの直後に読み戻して確かめる小さな検証を、ここに書き残します。

症状の見分け方 — 「作らない」ではなく「残らない」

最初にお伝えしたいのは、この症状は二つに分けて考えると迷わない、ということです。

症状よくある原因最初に確かめること
応答は成功、別の場所には存在する書き込み先のパスが想定とずれている応答が示した絶対パス、作業ディレクトリ
応答は成功、どこにも存在しない書き込みが反映されていない(権限、同期フォルダ、接続の状態)同じパスを読み戻した結果(ENOENT か否か)
既存ファイルの編集は通る、新規作成だけ消える新規作成の経路だけが別の挙動をしている新規作成と既存編集を別々に試す

コミュニティの報告には、ファイルシステム系の MCP サーバーで新規作成だけが成功応答のまま残らない、という事例があります。既存ファイルの編集と読み取りは安定しているのに、新規作成だけが消える——しかもアプリを再起動しても同じ、という内容です。クラウド同期のマウント配下で報告されている点も気になります。

私はこの報告を、原因の断定には使いません。同じ形の症状が実際に報告されているという手がかりとして読み、自分の環境で切り分けます。

原因を切り分ける順番

順番を決めておくと、慌てずに済みます。

  1. 応答に書かれたパスを、そのままコピーして ls -l に渡す。
  2. 見つからなければ、親ディレクトリを ls -la で見る。ディレクトリ自体が無いのか、ファイルだけが無いのか。
  3. 同じ操作を、同期されていないローカルフォルダ(たとえば /tmp 配下)で試す。
  4. 既存ファイルへの追記や編集が通るかを見る。
  5. 接続しているツールの一覧と状態を確認する。切れていれば、つなぎ直す。

3 番が要です。同期フォルダでだけ起きるなら、原因の候補は「書き込み経路」から「同期の層」へ絞れます。ローカルでも起きるなら、ツール側の問題として扱います。

直し方 — 書き込みの直後に読み戻す

切り分けより前に、被害を小さくする仕組みを一つ置いています。書いたら、必ず読み戻します。 応答の文言ではなく、ファイルの実体を見るということです。

次のスクリプトは、期待するファイルが存在し、空でなく、中身が一致するかを確かめます。何を解決するかといえば、「作成しました」という言葉を信じる代わりに、実体で次の工程へ進む可否を決めることです。

#!/usr/bin/env bash
# verify_written.sh — 書き込み直後の読み戻し検証
# 使い方: ./verify_written.sh <パス> [期待する文字列]
set -u
 
path="$1"
expect="${2:-}"
 
if [ ! -e "$path" ]; then
  echo "NG: 存在しません: $path" >&2
  ls -la "$(dirname "$path")" >&2 2>/dev/null || echo "NG: 親ディレクトリも見つかりません" >&2
  exit 1
fi
 
if [ ! -s "$path" ]; then
  echo "NG: 空ファイルです: $path" >&2
  exit 2
fi
 
if [ -n "$expect" ] && ! grep -qF -- "$expect" "$path"; then
  echo "NG: 期待した内容が含まれていません: $expect" >&2
  exit 3
fi
 
echo "OK: $(wc -c < "$path") bytes — $path"

なぜこう書くのかというと、終了コードを三種類に分けておくと、呼び出し側が「存在しない」「空」「内容違い」を区別できるからです。自動で回す処理でも、どこで止まったかがログに残ります。

Claude Code から使うなら、書き込みの直後に呼ぶ形が自然です。

# 例: 設定ファイルを作らせた直後の確認
./verify_written.sh ./config/app.settings.json '"version"' || echo "再作成が必要です"

Python で組み込む場合は、次の形になります。

from pathlib import Path
 
 
def verify_written(path: str, expect: str = "") -> None:
    """書いたはずのファイルを実体で確かめる。失敗なら例外で止める。"""
    p = Path(path)
    if not p.exists():
        raise FileNotFoundError(f"書き込みが残っていません: {p}")
    text = p.read_text(encoding="utf-8")
    if not text.strip():
        raise ValueError(f"空ファイルです: {p}")
    if expect and expect not in text:
        raise ValueError(f"期待した内容がありません: {expect!r}")
 
 
verify_written("./config/app.settings.json", '"version"')

なぜ応答の言葉だけでは足りないのか

応答は「ツールを呼んだ」という事実と、「ツールが成功を返した」という事実を伝えています。ただし、そのあとにファイルが残ったかどうかまでは、応答のどこにも書かれていません。

途中には、ツールの実装、OS の権限、同期クライアントといった層が挟まっています。どこか一層でも書き込みを取りこぼせば、上流は何も知らないまま「成功」を返してしまうのです。だから確かめる場所は、いちばん下流にある実体、つまりディスク上のファイルになります。

もう一つ、読み戻しは安上がりです。1 回あたりの手間はほんの数十ミリ秒で、見逃したときの手戻りに比べればはるかに小さな保険だと感じています。

直らないときの次の一手

読み戻しが失敗し、再作成しても同じなら、次の三つを順に試します。

  • 書き込み先を同期の外へ移す。 いったんローカルに作り、完成してから同期フォルダへコピーします。これで通るなら、同期の層が原因の可能性が高まります。
  • 新規作成をやめ、既存ファイルを編集する形にする。 空のテンプレートを先に手で置き、編集で中身を埋めます。報告にあった「編集は安定している」という観察に沿った、いわば回り道です。
  • 別の経路で書く。 ツール経由が不安定なら、Claude にシェルのコマンドで書かせ、同じ検証を通します。

どれも根治ではありません。それでも、検証が付いていれば、仕事が止まる前に気づけます。

私が決めた線引き

最初のうちは、応答を信じすぎていました。「作成しました」と言われれば、そのまま次の手順へ進んでいたのです。結果は芳しくありませんでした。存在しないファイルを前提にした処理が、あとから別のエラーとして現れ、原因を辿るのに余計な時間がかかりました。

いまは、こう決めています。言葉は参考に、実体は自分で。 書き込みの応答を受け取ったら、それが何であれ、読み戻して初めて「できた」と数えます。

まずは、いま使っている手順のうち、ファイルを新しく作らせる箇所を一つだけ選んで、直後に verify_written.sh を置いていただければと思います。私もそこから始めました。

シェア

お読みいただきありがとうございます

Claude Lab は広告なしで運営しており、サーバー費用などの運営コストはメンバーシップのご支援で賄っています。実装コード・ベンチマーク・本番設計パターンなど、実務でお役立ていただける記事を毎日更新しています。もし読んでよかったと感じていただけましたら、ぜひご覧ください。

  • ✦コピー&ペーストで使える実装コード付き
  • ✦毎日新しい上級ガイドを追加
  • ✦¥580/月 または ¥1,480 の永久アクセス
メンバーシップを見る →

もしこの記事がお役に立ちましたら、チップ(¥150)で応援いただけると大変励みになります。広告なしでの運営を続けるため、皆さまのご支援が大きな力になっています。

関連記事

◉ Claude.ai2026-10-03
使用量の上限が昼前に尽きた日、原因は送った回数ではなく一通の会話の長さでした
Pro や Max で「使用量の上限に達しました」が思ったより早く出たとき、Settings > Usage の二本のバー・その会話の往復数と添付・モデルと effort の順に見ています。昼前に止まった日の切り分けと、新しい会話へ移す線引きを書き残します。
◉ Claude.ai2026-07-09
Claude でカードが拒否されたときの完全対処ガイド — 原因別チェックリストと代替手段
Claude Pro/Max/APIの決済でカードが拒否される原因を、銀行側・Stripe側・Anthropic側の3層に分けて解説します。国際カード・3Dセキュア・VCNの落とし穴と、法人カード・Wise・Apple Payへの切り替え手順まで、実運用で詰まりやすいポイントをまとめました。
◉ Claude.ai2026-10-16
「出典を示して」と頼むのをやめて、回答の裏取りに使っている三つの聞き方
Claude の回答を文章に使う前に、「出典を示して」の代わりに使っている三つの聞き方を整理しました。分からないと言える余地を先に渡す、原文の引用を先に抜かせる、書いたあとで主張ごとに裏づけを探させる。それでも人が確かめる部分も書き残します。