Claude Media
Claude Codeのsshでpassphraseを聞かれて固まる原因と回避策

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の報告では、次の順で壊れます。

  1. Claudeがssh somehost trueや、git@github.com:形式のリモートへのgit fetchを実行する
  2. sshがEnter passphrase for key ...を画面に出す
  3. フルスクリーンのマウス追跡が止まり、マウス報告やエスケープシーケンスの生の文字列が画面に散らばる
  4. パスフレーズは入力できず、sshは失敗して終わる
  5. 終了して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 -l

Issueは再現条件として「ssh-add -lが鍵なしを返す、またはエージェントがいない」状態を挙げています。鍵のフィンガープリントが並ぶなら、少なくとも今のシェルでは条件から外れています。

気をつけたいのは、エージェントの有無はシェルごとに違う点です。ターミナルを開き直した直後や、sshで入ったリモートホストでは、エージェントが空のことがあります。Issueの報告者もリモートのLinuxホストでClaude Codeを動かしていました。

切り分け

ssh起因で固まったかの切り分け

  1. 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に再接続するため、壊れた状態のまま戻ります。報告者が出した手がかりは、そこまでです。

試せる順は次のとおりです。

  1. 壊れた端末タブを閉じ、新しい端末タブでclaude --resumeから再開する(別のptyになるため、端末モードの崩れは持ち越されない見込みです。Issueに明記された手順ではなく、仕組みからの推測です)
  2. 再開する前に、ssh-addで鍵を載せておく
  3. 同じ作業をもう一度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 /teleport fetches 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では試されていません。効くと決めつけず、まずはエージェント側で潰すのが安全です。

この記事を共有:XはてブLinkedIn