壁紙アプリの素材整理を一つのセッションに任せたまま、隣のウィンドウで受託サイトの原稿を直していた夜のことでした。翌朝そちらへ戻ると、つないでいたはずの MCP サーバーが一覧から消えており、ワークスペースの信頼を尋ねるダイアログがもう一度出てきました。
最初に疑ったのは自分の設定ミスです。前の晩に触った覚えのあるファイルを順に見返しましたが、書いた内容はそのまま残っておりました。消えるのはいつも「先に設定を変えたほうのセッション」の変更なのだと気づいたのは、三度目に同じことが起きたあとでした。
これは私の手癖の問題ではありませんでした。同時に走るセッションが互いの ~/.claude.json の変更を無言で巻き戻す不具合で、Claude Code の v2.1.259(2026年9月2日リリース) で修正されています。
先に結論として、いま確かめること
順番はこの三つで十分です。
- 手元の版を確かめて、v2.1.259 より前なら上げます。
- 消えている設定を洗い出して戻します。ここは自動では戻りません。
- 戻したあとで、設定ファイルのスナップショットを一度だけ取っておきます。
claude --version
# 上げる前に、いまの設定を退避しておきます
cp ~/.claude.json ~/.claude.json.$(date +%Y%m%d-%H%M%S).bak修正されたのは「これから壊れないこと」であって、すでに消えた分は戻ってきません。アップグレードだけで済ませてしまうと、消えたまま気づかない設定が残ります。
症状は「設定ミス」の顔をしてやってきます
この不具合のやっかいなところは、出てくる症状がどれも自分の操作ミスに見える点です。私は三日ほど、自分の手順書を疑って過ごしました。
| 目に見える症状 | 最初に疑ってしまうもの | 巻き戻しを疑う手がかり |
|---|---|---|
| ワークスペースの信頼ダイアログが再び出る | プロジェクトを開き直したせい | 同じパスで前日に承認済みである |
| MCP サーバーが一覧から消える | 設定ファイルの書き間違い | 設定ファイル側の記述は無傷である |
| プロジェクトごとの状態が初期化される | アップデートによる仕様変更 | 同時に開いていた別セッションだけ無事 |
見分けの決め手になったのは三列目の最後です。二つ開いていたうちの片方だけが元に戻り、もう片方は無事でした。設定ファイルの書式が悪いなら両方が同じように振る舞うはずで、片方だけというのは、外から上書きされたと考えるほうが自然でした。
なぜ後から書いた側が勝つのか
~/.claude.json は、セッションごとに読み込んで、変更が生じたときにまとめて書き戻される種類のファイルです。この読んで直して書き戻す形は、同じファイルを二つのプロセスが持っていると、あいだに入った他方の変更を静かに落とします。データベースの世界で lost update と呼ばれてきた形です。
厄介なのは、結果として書かれるファイルが壊れていないことです。JSON としては正しく、パースも通り、エラーも警告も出ません。ただ内容が数十分前に戻っているだけなのです。
壊れた設定は起動時に気づけますが、正しい形をした古い設定は、次に必要になる瞬間まで黙っています。
同じ性質の見つけにくさは設定ファイルの綴り違いにもあって、そちらはsettings.json のキー名を1文字間違えても、Claude Code は何も言わずに無視しますに書き残しております。原因は別ですが、「形が正しいので誰も止めてくれない」という点は同じでした。
消えた分を洗い出す小さなスクリプト
戻す作業で困るのは、何が消えたのかを思い出せないことです。私は記憶に頼るのをやめて、キーの経路だけを記録して差分を取るようにしました。
#!/usr/bin/env python3
"""~/.claude.json のキー経路を記録し、前回との差分を表示します。"""
import json
import datetime
import pathlib
SRC = pathlib.Path.home() / ".claude.json"
SNAP_DIR = pathlib.Path.home() / ".claude-config-snapshots"
MAX_DEPTH = 3
def key_paths(node, prefix="", depth=0):
# 値には履歴やトークン類が入りうるため、キーの経路だけを集めます
paths = set()
if isinstance(node, dict) and depth <= MAX_DEPTH:
for key, value in node.items():
path = f"{prefix}/{key}"
paths.add(path)
paths |= key_paths(value, path, depth + 1)
return paths
def main():
if not SRC.exists():
print(f"見つかりません: {SRC}")
return
SNAP_DIR.mkdir(exist_ok=True)
with SRC.open(encoding="utf-8") as handle:
current = key_paths(json.load(handle))
snapshots = sorted(SNAP_DIR.glob("*.txt"))
if snapshots:
previous = set(snapshots[-1].read_text(encoding="utf-8").splitlines())
lost = sorted(previous - current)
gained = sorted(current - previous)
for path in lost:
print(f"消えました: {path}")
for path in gained:
print(f"増えました: {path}")
if not lost and not gained:
print(f"差分はありません({len(current)} 経路)")
else:
print(f"初回のため差分は取りません({len(current)} 経路を記録します)")
stamp = datetime.datetime.now().strftime("%Y%m%d-%H%M%S")
target = SNAP_DIR / f"{stamp}.txt"
target.write_text("\n".join(sorted(current)), encoding="utf-8")
print(f"記録しました: {target}")
if __name__ == "__main__":
main()書き方について、二つだけ理由を添えます。
ひとつは、値を見ずにキーの経路だけを扱っている点です。この JSON には会話の履歴や認証まわりの情報が入りうるので、比較のために中身をファイルの外へ書き出したくありませんでした。経路だけでも「どのプロジェクトの、どの設定が消えたのか」は十分に分かります。
もうひとつは、特定のフィールド名を検査していない点です。私は最初、信頼済みかどうかを表すフィールドを名指しで見に行く書き方をしておりました。ところがこのファイルは公開された取り決めではなく、版によって構造が変わります。名指しの検査は、名前が変わった版で「そのキーが無い=異常なし」と読めてしまい、無言で通ってしまうのです。キー集合の差分にしておけば、名前が変わったことも「消えました」と「増えました」の対として現れます。
出力を眺めながら、消えた経路に対応する設定を一つずつ戻します。MCP サーバーであれば claude mcp list で現状を確かめ、足りないものを追加し直します。信頼の承認は、そのディレクトリでもう一度セッションを開けば尋ねられます。
上げたあとも残している線引き
修正が入ってからも、私は次の三つを続けています。直ったのは Claude Code の側であって、同じファイルに触る自分のバックアップ処理や棚卸しのスクリプトまで直るわけではないからです。
- 設定を変える操作(MCP の追加、信頼の承認、プラグインの導入)は、一つのセッションだけで行います。そのあいだ他のセッションは閉じます。
- 変更したら、上のスクリプトを走らせてスナップショットを一枚残します。所要は数秒です。
- 無人で走らせている定期処理には、設定ファイルを読ませても書かせません。書く必要が出たときは、その処理を手元での実行に切り替えます。
設定を書く口はひとつに、読む口はいくつでも。 修正が入ったいまとなっては、三つ目の決めごとは過剰かもしれません。それでも並列で作業する日ほど、この一行だけは守るようにしております。
長い処理を別のセッションへ預けたまま待つ場面での取り決めについては、長い処理を別セッションに任せて待つ — 通知が届かなかったときのための完了マーカーにも書きました。二つ目のプロセスが割り込んでくる問題をロックファイルの側から扱った記事として、連携フォルダに置いたロックが、二度目の無人実行を締め出すまでもあります。
次の一歩
まず claude --version を打ってみてください。v2.1.259 より前であれば上げて、その足で上のスクリプトを一度だけ走らせ、最初のスナップショットを作っておくことをおすすめします。次に何かが消えたとき、原因を探す前に「消えたかどうか」だけは一分で判断できるようになります。
同じところで三日ぶんの朝を溶かした身として、どなたかの手が止まる時間が短くなればと願っております。ここまでお付き合いくださり、ありがとうございました。