← 他の Claude Code 安全ツール

Claude Code のセッションが 400 thinking blocks cannot be modified
二度と開けなくなった時の救出ツール

拡張思考(extended thinking)とツール呼び出しを使った長いセッションを resumecontinue した瞬間、API Error: 400 … `thinking` or `redacted_thinking` blocks in the latest assistant message cannot be modified が出て、そのセッションが二度と開けなくなる事故があります。何を打っても、何も打たなくても、同じ 400 が返り続けます。何時間ぶんもの会話が、開いた瞬間に永久に閉じ込められます。

原因(要約)。 Claude Code はセッションの記録(~/.claude/projects/<slug>/<id>.jsonl)に拡張思考のブロックを保存する時、thinking のテキストを空("")にしたまま signature だけを残します。resume などで記録から会話を組み直すと、この「中身が空なのに署名つき」のブロックがそのまま API に送られ、署名が本文と一致せず 400 になります。元の thinking の本文はもうディスクに無いので、正しい形に戻せず、セッションが永久に汚染されます。これは特殊な状態ではなく、拡張思考を使ったほぼ全てのセッションが、一度の組み直し(resume / continue / 離席からの復帰の自動圧縮)でこの状態になり得ます。

このツールがすること。 壊れた .jsonl を下の枠に渡すと、署名つきの空 thinking ブロックを取り除いた復旧版をブラウザの中だけで作って返します。thinking だけだった行は [thinking] というテキストの目印に置き換えて、ツール呼び出しの対応関係(threading)を壊しません。ファイルはどこにも送信しません(全てこのページの中で処理)。元ファイルは触らず、復旧版をダウンロードする方式です。

壊れた .jsonl をここにドラッグ、またはクリックして選択 ~/.claude/projects/<slug>/<セッションID>.jsonl
送信は発生しません(このページの中だけで処理します)

復旧の手順

  1. 事故が起きたセッションの .jsonl を上の枠に渡す。場所は ~/.claude/projects/ の中の、プロジェクトごとのフォルダにあります(ファイル名がセッションID)。
  2. 判定が出たら、復旧版をダウンロードする。
  3. 元ファイルをまず退避してから、復旧版で置き換える。ターミナルなら次の通り(<path> は元ファイルの場所):
    cp "<path>" "<path>.bak"      # 念のため元を退避
    mv ~/Downloads/<復旧版>.jsonl "<path>"
  4. もう一度 claude --resume でそのセッションを開く。署名つきの空ブロックが無くなっているので、400 は出なくなります。おかしければ mv "<path>.bak" "<path>" で元に戻せます。

ターミナルだけで直したい場合

ブラウザを使わず、同じ処理を手元で走らせるスクリプトです(先に .bak へ退避します)。

F="$HOME/.claude/projects/<slug>/<session-id>.jsonl"
python3 - "$F" <<'PY'
import json, sys, shutil
f = sys.argv[1]
shutil.copy2(f, f + ".bak")
out = []
for line in open(f, encoding="utf-8"):
    line = line.rstrip("\n")
    if not line: continue
    o = json.loads(line)
    msg = o.get("message")
    if isinstance(msg, dict) and isinstance(msg.get("content"), list):
        new = [b for b in msg["content"]
               if not (isinstance(b, dict) and b.get("type") in ("thinking","redacted_thinking"))]
        if len(new) != len(msg["content"]):
            msg["content"] = new or [{"type":"text","text":"[thinking]"}]
    out.append(json.dumps(o, ensure_ascii=False))
open(f, "w", encoding="utf-8").write("\n".join(out) + "\n")
print("rescued; backup at", f + ".bak")
PY

resume の前に、壊れていないか先に確かめる

大事なセッションは、resume する前にこの読み取りだけのチェックで「組み直すと 400 になる種」を持っていないか確認できます。0 より大きければ、resume の前にコピーを取っておくのが安全です。

grep -c '"type":"thinking","thinking":""' "$HOME/.claude/projects/<slug>/<session-id>.jsonl"
こうした「気づけない静かなデータの喪失」を実行の手前で止める無料のフック集が cc-safe-setup です(rm -rf や強制 push、秘密の漏れ、壊れたデプロイを止める例を多数収録)。
「道具が成功と報告したのに、実際にはデータが静かに失われていた」型の事故を、体験と防御の手順でまとめた読み物が Claude Code 事故防止ハンドブック です。

本当の直し方について(正直に)

根本の修正は Claude Code 側(thinking の本文も保存する、または組み直しの時に末尾の署名つきブロックを落とす)でしか出来ません。このツールは、それまでの間、閉じ込められた会話を失わずにセッションを開き直すための応急の救出です。元ファイルは退避してから置き換えてください。署名を消すので、その assistant の応答は次回以降「思考の過程」を持たない形になりますが、会話の本文とツールの結果はそのまま残ります。