Claude Codeのsshでpassphraseを聞かれて固まる原因と回避策
Bashツールのsshがパスフレーズを要求すると、フルスクリーンのマウス操作が壊れ、resumeしても直らない報告があります。原因と、ssh-agentで防ぐ回避策をまとめます。
Claude CodeのBashツールでsshやgit fetch(SSH経由)が動き、鍵のパスフレーズを聞かれた瞬間に画面が崩れる。マウスは効かず、キー入力も乱れ、resumeで開き直しても同じ状態に戻る。GitHubのIssue #97297は、この症状をBashツールの子プロセスがTUIの実ptyを継承する回帰として報告しています。
回避の軸は単純で、パスフレーズを聞かれる状況そのものを作らないことです。鍵をssh-agentに載せてからClaude Codeを起動し、sshには対話を禁じるオプションを付けます。
症状:sshが走った途端にマウスもキー入力も効かなくなる
Issueの報告では、次の順で壊れます。
- Claudeが
ssh somehost trueや、git@github.com:形式のリモートへのgit fetchを実行する - sshが
Enter passphrase for key ...を画面に出す - フルスクリーンのマウス追跡が止まり、マウス報告やエスケープシーケンスの生の文字列が画面に散らばる
- パスフレーズは入力できず、sshは失敗して終わる
- 終了して
resumeしても、壊れた状態のまま戻ってくる
エラーメッセージは出ません。報告者のログ欄にも「使えるエラーは出ない」とだけあります。そのため、原因がsshだと気づくまでに時間がかかる型の不具合です。
報告された環境はUbuntu 26.04のLinuxホストで、iTerm2(macOSからLinuxへssh接続)とChromeOSのターミナルアプリの両方で再現しています。Claude Codeは2.1.282で確認、2.1.280までは起きず、2.1.281で初めて見たという内容です。macOS上のローカル実行での報告はIssueにありません。
原因:Bashの子プロセスがTUIの端末を開ける
報告者の見立ては次のとおりです。BashツールがClaude Codeの子プロセスを起動するとき、子プロセスがTUIの動いている実ptyを制御端末として持ったままになる。すると子プロセスは/dev/ttyを開いて、端末のモード(エコーのオフなど)を書き換えられます。
sshはパスフレーズが必要で、かつ鍵がエージェントに載っていないと、標準入力ではなく/dev/ttyを開いてプロンプトを出します。その相手がClaude Code自身の端末なので、次のことが同時に起きます。
- 端末のモードがClaude Codeの足元で変わり、マウス追跡とキー入力が壊れる
- sshとClaude Codeが同じttyを読み合い、パスフレーズ入力が成立しない
resumeは同じptyに再接続するため、壊れた状態を引き継ぐ
報告者が期待する修正は2つあります。子プロセスをsetsidなどで別セッションに置いて制御端末を持たせないこと、そしてresume時に端末の状態(マウス追跡や代替画面)を初期化することです。どちらも提案であり、実装されたとはIssueに書かれていません。
フルスクリーンモードが代替画面を使い、マウスイベントをClaude Code自身が受け取る仕組みはClaude CodeのTUI(フルスクリーン)の解説にまとめています。マウス捕捉が前提の画面だからこそ、端末モードの書き換えが目に見える崩れになります。
自分の環境で再現条件に当たるか確かめる
条件は「パスフレーズ付きの鍵が~/.sshにあり、エージェントがその鍵を保持していない」ことです。Claude Codeを起動する前に、次の1行で確かめられます。
ssh-add -lIssueは再現条件として「ssh-add -lが鍵なしを返す、またはエージェントがいない」状態を挙げています。鍵のフィンガープリントが並ぶなら、少なくとも今のシェルでは条件から外れています。
気をつけたいのは、エージェントの有無はシェルごとに違う点です。ターミナルを開き直した直後や、sshで入ったリモートホストでは、エージェントが空のことがあります。Issueの報告者もリモートのLinuxホストでClaude Codeを動かしていました。
ssh起因で固まったかの切り分け
- Q固まる直前にClaudeがssh、またはgit fetchなどSSH経由の操作を実行したか?答えが別の原因です。入力が効かない系の症状は下の「近い症状との見分け」を見ます
下の回避策で、パスフレーズを聞かれる状況を先に潰します。
回避1:鍵をssh-agentに載せてからClaude Codeを起動する
パスフレーズの要求が出なければ、/dev/ttyは開かれません。エージェントに鍵を載せる操作は、Claude Codeの外のシェルで済ませます。
ssh-add ~/.ssh/id_ed25519 # ここでパスフレーズを入力する
ssh-add -l # 鍵が載ったことを確認する
claude鍵のファイル名は環境ごとに違います。ここでは例としてid_ed25519を使っています。
~/.ssh/configのAddKeysToAgent yesは、初回のssh接続で鍵をエージェントに自動登録する設定です。ただし初回の接続ではパスフレーズを聞かれます。その初回がClaude Codeの中のBashツールだと、この不具合に当たります。設定を入れた場合も、最初の1回はClaude Codeの外でsshを通しておく必要があります。
回避2:sshに対話させない設定を足す
エージェントが空でも崩れないようにするには、sshの側で端末への問い合わせを禁じます。OpenSSHのBatchModeは、パスフレーズやパスワードの問い合わせを無効にするオプションです。
ssh -o BatchMode=yes somehost true
GIT_SSH_COMMAND='ssh -o BatchMode=yes' git fetchこの設定でsshは、聞く代わりにPermission denied (publickey)のような形で失敗します。失敗の文面はClaudeに返るので、「鍵をエージェントに載せてください」と人に頼む判断をClaude側に任せられます。Issueが期待動作として挙げているのも、UIに触れずにsshが素直に失敗する挙動です。
HTTPSリモートの認証でも似た事故があります。Issue #45857は、プラグインのインストールでgitがHTTPSの資格情報を端末に問い合わせ、Claude Codeのキー入力を奪った報告です。このIssueは重複として閉じられています。報告者は、Claude Codeがプラグイン用のgitにGIT_TERMINAL_PROMPT=0を設定していないことを原因に挙げています。
CLAUDE.mdに規約として書いておく
Claudeにsshを使わせる場面が多いなら、プロジェクトのCLAUDE.mdに次の2行を置く方法があります。コマンドを組み立てるのはClaudeなので、毎回オプションを付けさせる運用です。
## SSH / git の実行ルール
- ssh は必ず `-o BatchMode=yes` を付けて実行する。パスフレーズを聞かれる状況では実行せず、ユーザーに `ssh-add` を頼む
- SSH リモートへの git 操作は `GIT_SSH_COMMAND='ssh -o BatchMode=yes'` を前置するこれは再発を確実に防ぐ仕組みではなく、Claudeの判断に寄せた緩和策です。確実さが要るなら、回避1でエージェントに鍵を載せるほうが筋のよい手段です。
固まったセッションをどう戻すか
Issueの報告では、resumeは同じptyに再接続するため、壊れた状態のまま戻ります。報告者が出した手がかりは、そこまでです。
試せる順は次のとおりです。
- 壊れた端末タブを閉じ、新しい端末タブで
claude --resumeから再開する(別のptyになるため、端末モードの崩れは持ち越されない見込みです。Issueに明記された手順ではなく、仕組みからの推測です) - 再開する前に、
ssh-addで鍵を載せておく - 同じ作業をもう一度Claudeに頼む
同じIssueのコメントには、resume時にマウス追跡など端末の捕捉を自動で復元するようになり、緩和されたように見える、という書き込みが1件あります。コメントの投稿者による観察で、どのバージョンで入ったかは書かれていません。
修正状況とバージョンの読み方
Issue #97297は、2026-09-25に立てられ、openのままです。最後の更新は上記コメントの2026-09-30です。labelにはbug、has repro、regression、area:tui、area:bashがついています。
changelogでpassphraseに触れる項目は、2.1.285にある次の1件です。
Fixed SSH passphrase and new-host prompts from worktree and
/teleportfetches taking over the terminal; these fetches now fail fast instead of asking
これはClaude Code自身が実行するworktreeと/teleportの取得処理の修正です。ユーザーの指示でBashツールが走らせたsshは対象に書かれていません。Issueの症状とは経路が違うと見るのが妥当です。
整理すると、sshをBashツール経由で動かす場面については、changelogにこの不具合の修正を明言した項目がありません。更新で直ったかどうかは、Issueの状態とchangelogの両方で確かめる必要があります。
近い症状との見分け
パスフレーズに絡む症状は、原因が別のものがいくつかあります。
| 症状 | 状況 | 向かう先 |
|---|---|---|
| UIが崩れ、マウスが効かない | 状況フルスクリーンでsshがパスフレーズを要求 | 向かう先この記事の回避1・2 |
プロンプトが出ずPermission denied (publickey) | 状況ssh_askpassが見つからないLinux(Issue #17223、2.1.3での報告、not plannedで閉鎖) | 向かう先鍵をエージェントに載せる |
| sandbox内でだけsshが落ちる | 状況Network is unreachableなど | 向かう先sandboxのpsqlとsshの回避 |
| sandbox内でgitのSSHリモートだけ落ちる(macOS) | 状況sandboxの制約 | 向かう先sandboxでgit SSHだけ失敗する原因 |
Issue #17223は、パスフレーズのプロンプトがそもそも表示されなくなった、という逆向きの報告です。2つのIssueを合わせると、「聞かれて崩れる」と「聞かれず失敗する」の両方が、Bashツールの端末の扱いに由来する可能性が見えます。ただし#17223は2.1.3の報告で、#97297の回帰とは時期も症状も別です。
まとめ
Bashツールのsshがパスフレーズを求めると、フルスクリーンの端末が壊れる報告があり、Issueはopenです。鍵を事前にssh-agentへ載せ、sshをBatchMode=yesで動かす2段にすれば、条件に当たらずに済みます。
フルスクリーンのマウス捕捉そのものを切るCLAUDE_CODE_DISABLE_MOUSE=1が、この崩れを防ぐかどうかは、Issueでは試されていません。効くと決めつけず、まずはエージェント側で潰すのが安全です。