Claude Codeの--session-idと--no-session-persistenceの使い方
--session-idでセッションIDを固定し、--no-session-persistenceで履歴を残さない起動オプションです。CI・自動化スクリプトでの使い分けを解説します。
--session-idは起動する会話にUUID形式のセッションIDを自分で割り当てるフラグです。--no-session-persistenceは会話をディスクに保存せず、あとから--resumeで呼び出せない状態で実行するフラグです。日常の対話利用ではまず触りませんが、CIやスクリプトからclaudeを呼ぶ場面では、結果とセッションの対応付けや履歴の残り方を左右します。
手元のclaude --helpに出る3つのフラグ
v2.1.287でclaude --helpを実行すると、関連するフラグは次のように表示されます(該当部分を抜粋)。
-n, --name <name> Set a display name for this session
(shown in the prompt box, /resume
picker, and terminal title)
--no-session-persistence Disable session persistence - sessions
will not be saved to disk and cannot be
resumed (only works with --print)
--session-id <uuid> Use a specific session ID for the
conversation (must be a valid UUID)--no-session-persistenceの説明の末尾にonly works with --printとあります。つまり-p(--print)付きの実行が前提です。以降の節は、この一行が運用にどう効くかを軸に進めます。
セッションIDを自分で決める --session-id
指定しなければ、Claude Codeが起動のたびにIDを自動で発行します。--session-idはこの既定のIDを、あらかじめ決めた値に置き換えます。値は有効なUUIDでなければなりません。
claude --session-id "550e8400-e29b-41d4-a716-446655440000"後段の処理と対応付けたいなら、uuidgenなどで生成した値を渡す形が扱いやすくなります。デプロイスクリプトから呼ぶ場合、発行したIDをジョブのログにも書き出しておけば、実行結果とセッションをあとから突き合わせられます。
claude -p --session-id "$(uuidgen)" "デプロイログを要約して"IDを事前に決める必要がないなら、別の取り方もあります。claude -pに--output-format jsonを付けると、返ってくるJSONのsession_idにIDが入っています。このIDを変数に取っておき、次の呼び出しで--resumeに渡せます。呼ぶ前にIDを知っておきたいときだけ--session-id、実行後に拾えれば足りるときはJSONのsession_id、と使い分けられます。
IDで再開するときの探索順序
E2Eテストのシナリオごとに固定のUUIDを渡しておけば、失敗時にclaude --resume <同じUUID>でその会話を開けます。このとき、IDは次の順序で探されます。
--resume <session-id> の探索
- 1
今のプロジェクトディレクトリとgit worktree
最初にここを探します。見つかればその会話を再開します。
- 2
マシン上の他のプロジェクト
見つからなければ他の全プロジェクトへ広げます。ただし解決するのは、そのIDの会話が入った記録がちょうど1つのプロジェクトにあるときだけです。
- 3
見つからない場合
No conversation found with session ID: <session-id>と表示されます。手でコピーした重複ファイルがあるときも、どれかを選んで再開せずこのエラーになります。
v2.1.223より前は、探索が今のプロジェクトディレクトリとworktreeで止まっていました。UUIDはシナリオごとに別の値を振っておくと、重複による見つからないエラーを避けられます。
会話の記録は~/.claude/projects/<project>/<session-id>.jsonlに保存されます。<project>は作業ディレクトリのパスの英数字以外を-に置き換えた名前です。--resumeには、IDの代わりにこの.jsonlファイルの絶対パスも渡せます。保存場所を~/.claudeの外へ移すならCLAUDE_CONFIG_DIR、保存期間の既定は30日で、cleanupPeriodDaysで変えられます。
変換後のディレクトリ名が200文字を超える作業ディレクトリでは、名前を200文字に切り詰め、フルパスのハッシュを末尾に付けます。CIで作業ディレクトリが毎回変わると、記録の置き場所も毎回変わります。v2.1.234以降は、CLAUDE_CODE_PROJECT_DIR_NAMEをCLAUDE_CONFIG_DIRと併用して、projects/下のディレクトリ名を固定できます。
--no-session-persistenceで履歴を残さない
--no-session-persistenceを付けると、会話がディスクに保存されません。保存されないので、あとから--resumeでは呼び出せません。
claude -p --no-session-persistence "一時的な質問"print modeのセッションは、このフラグがなくても既定で--continueの対象から外れ、セッションピッカーにも出ません。それでも、IDを渡せばclaude --resume <session-id>で再開できます。claude -p --continueのように-pと組み合わせると対象に含まれます。--no-session-persistenceはここから踏み込み、保存そのものを止めます。「一覧に出ないだけ」と「そもそも残らない」は別の状態で、後者になるのがこのフラグです。
CLAUDE_CODE_SKIP_PROMPT_HISTORYは全モードで効く
CLAUDE_CODE_SKIP_PROMPT_HISTORYを1に設定すると、プロンプト履歴とセッションのトランスクリプトをディスクに書き込みません。このセッションは--resume、--continue、上矢印キーの履歴のどれにも出てきません。フラグと違い、どのモードでも効きます。
使い捨てのスクリプトセッションなら環境変数、print modeの1回きりの呼び出しだけならフラグ、という選び方です。screenやバックグラウンドランチャー経由の独立したセッションが入れ子と誤判定され、履歴が残らないこともあります。その対処法はFORCE_SESSION_PERSISTENCEでセッション消失の誤判定を止めるにあります。
子プロセスやログからセッションIDを辿る
CLAUDE_CODE_SESSION_IDでサブプロセス側からIDを参照する
CLAUDE_CODE_SESSION_IDは、BashやPowerShellツール、hookコマンド、stdio接続のMCPサーバーの各サブプロセスに自動でセットされる環境変数です。Bash・PowerShell・hookでは、hookのJSON入力のsession_idフィールドと一致し、/clearのたびに更新されます。
MCPサーバーのサブプロセスだけは、起動時に渡されたIDを保持し続けます。--resume <session-id>で再開した場合はそのIDを受け取ります。IDを指定しない--continueや--resumeでは、起動時点のIDのままになることがあります。
デバッグログ(--debugなどで有効化)の既定の出力先は~/.claude/debug/<session-id>.txtです。--debug-fileかCLAUDE_CODE_DEBUG_LOGS_DIRで変えられます。
--fork-sessionは再開時に新しいIDを作る
--session-idと混同しやすいのが--fork-sessionです。
IDを付ける場面が逆の2つ
--session-id
これから始める会話に、決めたUUIDを割り当てます。
--fork-session
--resumeや--continueと組み合わせ、元のIDを使わず新しいIDを発行します。元の会話はそのまま残ります。
実行中のバックグラウンドセッションは、v2.1.285以降はclaude --resume <ID>でそのセッション自体を開きます。パイプ入出力、--output-format json、--model、--max-turnsなどを付けた呼び出しや、agent viewを無効にした環境では、開かずに終了コード1で止まります。このときは--fork-sessionを付けて、会話のコピーを再開します。
同じ分岐でも、別プロセスで--fork-sessionを使うと、新しいプロセスには権限の承認が引き継がれません。同一プロセス内の/branchは引き継ぐので、承認をやり直したくないなら/branchのほうが手間は小さくなります。
--name/-nは人が読める名前
--session-idが指定するのは処理向けのUUIDです。人が探しやすい名前を付けたいなら--name(-n)を使います。名前は/resumeの一覧とターミナルのタイトルに表示され、claude --resume <name>で呼び出せます。
claude -n "auth-refactor"インタラクティブセッションで同名のセッションがすでに動いていると、名前は先に使っているほうに残ります。あとから起動したほうはauth-refactor-graceful-unicornのような2語の接尾辞付きの変種名になります。名前を付けるとタブタイトルも名前に変わります。タブには会話から生成されたタイトルを残したいなら、設定ファイルでterminalTitleFromRenameをfalseにします。名前そのものは有効なままで、/resume <name>の検索にも使えます。
v2.1.232より前は、同名のセッションが両方とも名前を保持していました。また、-pやバックグラウンドのセッションは起動時に--nameの重複を確認しません。CIでclaude -p -nを並列に走らせると同名のセッションが並ぶことがあるため、確実に区別したい場面では--session-idのUUIDを使います。
使い分け早見表
| 項目 | 何をするか | 効く範囲 |
|---|---|---|
--session-id | 何をするか新規セッションにUUIDを割り当てる | 効く範囲全モード |
--no-session-persistence | 何をするかセッションを保存せず再開不可にする | 効く範囲print modeのみ |
CLAUDE_CODE_SKIP_PROMPT_HISTORY=1 | 何をするか履歴とトランスクリプトの書き込みを止める | 効く範囲全モード |
--fork-session | 何をするか再開時に元のIDを使わず新しいIDを発行する | 効く範囲--resume/--continue時 |
CLAUDE_CODE_SESSION_ID | 何をするかサブプロセスに現在のセッションIDを渡す | 効く範囲Bash/PowerShell/hook/MCP |
--name, -n | 何をするか表示名を付けて--resumeで探しやすくする | 効く範囲全モード |
CI/CDで2つのフラグを組み合わせる
CIパイプラインやバッチスクリプトでは、組み合わせて使う場面が多くなります。実行のたびにログへ紐づくIDを発行しつつ、ディスクには会話を残さない構成です。
claude -p --session-id "$(uuidgen)" --no-session-persistence \
--output-format json "CIログのエラー原因を要約して"この構成では、会話が保存されないので、IDを控えていても--resumeでは開けません。IDの役割は再開ではなく、ログとの突き合わせに限られます。失敗時に会話を開き直したいE2Eテストのような用途では、--no-session-persistenceを付けません。
突き合わせに使えるIDの出どころは3か所あります。
同じIDが現れる3か所
CIのジョブログ
uuidgenで作った値を、スクリプト側でそのまま書き出します。hookのJSON入力
session_idフィールドの値を、ツール呼び出し1件ごとの記録と照合できます。Bashツールの環境変数
CLAUDE_CODE_SESSION_IDの値を、スクリプト自身のログに書き添えられます。
--session-idが受け取るのは有効なUUIDだけです。ジョブIDやコミットハッシュのような独自の識別子は、そのままでは渡せません。UUIDとジョブIDの両方をログに残して、あとから紐づけます。uuidgenはmacOSや多くのLinux環境で使えます。
起動時オプションの読み方をさらに知りたい場合は、append-system-promptとsystem-promptの違いや、--mcp-configと--strict-mcp-configの使い分けも参考になります。--resumeでセッションが見つからないときの原因は、「No conversation found with session ID」の対処法にまとめました。