Claude Desktopのターミナルでfishが固まる原因 — 10秒待ちの正体
Claude Desktop内蔵ターミナルでfish 4.xが起動のたびに10秒止まり、警告を出す件の原因はDA1(端末属性の問い合わせ)への無応答です。警告の意味と回避策、副作用をまとめます。
Claude Desktopの内蔵ターミナルでfish 4.xを開くと、プロンプトが出るまで毎回10秒待たされることがあります。原因は、fishが起動時に送る端末属性の問い合わせ(DA1)にDesktopのターミナルが返事をしないことです。set -Ua fish_features no-query-termで待ちは消えますが、fishの端末機能の検出も止まります。
症状: 10秒止まってから警告が出る
報告されている環境は、macOS上のClaude Code Desktopアプリ(CLIのバージョンは2.1.235)、fish 4.7.1です。アプリ内でターミナルを開くたびに約10秒止まり、その後に次の警告が出ます。
warning: fish could not read response to Primary Device Attribute query
after waiting for 10 seconds. This is often due to a missing feature in
your terminal. See 'help terminal-compatibility' or 'man
fish-terminal-compatibility'. This fish process will no longer wait for
outstanding queries, which disables some optional features.(警告は読みやすいよう改行を入れています。)
警告の後でプロンプトは通常どおり出ます。止まるのは起動直後だけで、その後の入力やclaudeの実行が遅くなる、という報告はありません。ターミナルを新しく開くたびに繰り返すため、タブを何枚も開く使い方ほど待ち時間が積み重なります。
原因: DA1に返事がない
DA1(Primary Device Attributes)は、アプリが端末に「あなたは何ができる端末か」と尋ねる制御シーケンス\e[0cです。端末は\e[?で始まりcで終わる返事を返す決まりになっています。
fishの端末互換性のドキュメントは、DA1を「必須のコマンド」に分類しています。実装されていないと、起動時に短い停止があり、その後に警告が出るとの説明です。つまり10秒待ちはfishの不具合ではなく、必須の問い合わせに端末が応えない場合の想定された挙動です。
報告では、fish 4.1以降がこの問い合わせを起動時に送り、最大10秒返事を待つとされています。待ちきれなかったfishは、以降は未回答の問い合わせを待たなくなり、オプションの機能を無効にします。報告者によれば、xterm.js系を含む多くのエミュレーターはDA1に答えます。期待される動作は、Desktopの内蔵ターミナルが\e[?1;2cのような返事を返すことです。
回避策: query-termを切ると何が失われるか
fishのドキュメントは、端末が非互換のときの一時的な逃げ道として、query-term機能フラグを切る方法を載せています。
set -Ua fish_features no-query-termissueの回避策は-U(ユニバーサル変数)で同じ設定を入れる形で、ドキュメントの例は-Ua(既存の値に追記)です。fish_featuresにすでに別の値を入れている場合は、上書きしない追記の形が安全です。機能フラグは起動時にしか読まれないため、設定後に開き直したターミナルから効きます。
ここで押さえておきたい点が2つあります。
- 設定はDesktopだけに効くわけではありません。ユニバーサル変数はそのユーザーのすべてのfishに及び、iTerm2やGhosttyなどの他のターミナルでも端末の問い合わせが止まります。報告者もこの点を欠点として挙げています。
- 失う機能の全体像は一覧で確認できません。ドキュメントは「スクロールなどの機能が有効になる」と説明するだけで、機能ごとの対応表は載せていません。
戻したいときは、設定を消します。fish_featuresに他の値を入れていなければ、次で足ります。
set -Ue fish_features他の値を入れている場合、このコマンドは全部消すので、set -S fish_featuresで中身を見てから設定し直してください。
fishは端末に何を問い合わせているのか
10秒待ちの理由を理解するには、fishが端末に何を尋ねているかを知っておくと便利です。fishの端末互換性ドキュメントは、端末への要求を「必須」と「任意」に分けています。必須に挙がるのはカーソル移動や画面消去などの基本的な制御と、DA1の応答です。 任意の側には、問い合わせ型のシーケンスがいくつか並びます。ドキュメントの説明は次のとおりです。
| 問い合わせ | 用途(ドキュメントの説明) |
|---|---|
カーソル位置の報告(\e[6n) | 用途(ドキュメントの説明)複数行の自動補完候補を画面下端で切り詰める。スクロールバック送りの機能やクリックでのカーソル移動にも使う |
| 端末名とバージョン(XTVERSION) | 用途(ドキュメントの説明)非互換な端末への一時的な回避策にだけ使う |
背景色(\e]11;?) | 用途(ドキュメントの説明)fish_terminal_color_themeを埋め、明暗に合ったテーマを選ぶ |
| 端末情報(XTGETTCAP) | 用途(ドキュメントの説明)indnなどの端末機能の有無や、OSの種類の取得 |
kitty keyboard protocol(\e[=...u) | 用途(ドキュメントの説明)キー入力の判別を細かくするプロトコルを有効にする |
DA1だけが「必須」で、他はすべて任意です。したがって端末がこれらに答えなくても、fishは基本機能のまま動きます。DA1に答えない端末で起きるのは、10秒の待ちと警告です。この警告が出た後は、未回答の問い合わせを待たなくなり、任意の機能が無効になります。
query-termを切った場合に、上の表のどれが止まるのかをドキュメントは項目別には書いていません。書かれているのは、端末へ問い合わせて返事を読むための機能であり、スクロールなどが使えるようになる、という説明です。DA1の説明にある「起動時の短い停止と警告」も、このフラグで消せるとされています。
回避策をDesktopだけに絞れるか
副作用が全端末に及ぶなら、Desktopだけに効かせたい、と考えるのは自然です。ドキュメントを読む限り、手がかりは2つあります。
fish --features qmark-noglob,regex-easyescのように、起動時の引数で機能フラグを指定できる。これはそのセッションだけに効く- 機能フラグの変数は起動時にしか読まれず、ユニバーサル変数か、エクスポートされた変数でなければ効かない
ただし、ドキュメントの例は機能を有効にする向きの指定だけです。fishの機能フラグの説明には、no-query-termを--featuresで渡す例も、Desktopの内蔵ターミナルを見分ける環境変数も載っていません。
エクスポートした値が効くという記述の範囲で言えるのは、fish_featuresをエクスポートしたシェルから起動した子のfishに、その値が引き継がれることまでです。Desktopの内蔵ターミナルだけを狙い撃ちする設定の書き方は、この記述からは導けません。config.fishは起動処理の後に読まれるため、そこで値を入れても、すでに動いているセッションには効かないはずです。
環境変数での分岐そのものは、fishのドキュメントにも前例があります。GNU screenでは、DCSコマンドの扱いが非互換で最初のプロンプトが崩れることがあり、fishはSTY環境変数の有無を見て回避しています。つまり「端末固有の環境変数で挙動を分ける」発想は、fish自身も使っています。ただしこれはscreen向けの話で、Desktopに当てはめられる情報ではありません。
回避策の文言にも注意が要ります。ドキュメントはno-query-termを「for the time being(当面は)」の逃げ道と書いています。ここで引いた記述はfish 4.9.3版のドキュメントのもので、位置づけは当面の策です。Desktop側が将来DA1に答えるようになれば、回避策を外して機能検出を戻せます。
回避策か待ちか: 使い方別の判断
回避策を入れるかは、fishを使う範囲で決まります。
| fishの使い方 | 回避策の副作用 | 向く選択 |
|---|---|---|
| Desktopでしか使わない | 回避策の副作用ほぼ出ない | 向く選択no-query-termで待ちを消す |
| 他の端末でも日常的に使う | 回避策の副作用他の端末でも端末機能の検出が止まる | 向く選択10秒の待ちを受け入れる |
| Desktopでたまにしか開かない | 回避策の副作用待ちの影響が小さい | 向く選択設定を変えずに様子を見る |
| タブを何枚も開く | 回避策の副作用待ちが積み重なる | 向く選択回避策を入れる価値が出やすい |
待ちは最大10秒で、fishを起動するたびに発生します。タブを5枚開けば、1枚目から5枚目まででそれぞれ最大10秒、合計で最大50秒です。1回の待ちは短くても、開閉の多い使い方では合計が無視できません。報告で止まるとされているのは起動時で、起動後のシェルの操作が遅くなるという記述はありません。
設定が効いているかを確かめる
設定後は、フラグの状態と、端末側の機能の検出結果を見て確かめられます。ドキュメントに載っているコマンドは次のとおりです。
status features
status test-terminal-features scroll-content-up
echo $fish_terminal_color_themestatus featuresは機能フラグの一覧を出し、query-termの行がonかoffかで状態が分かります。回避策が効いていれば、query-termはoffになるはずです。
2行目のstatus test-terminal-features scroll-content-upは、端末がスクロールの機能に対応していると検出したときに終了ステータス0を返します。3行目のfish_terminal_color_themeは、端末が明暗の別を報告するとlightかdarkになり、報告しないとunknownになります。どちらも、最初のプロンプトが出た後に値が入る仕様です。
DA1に答えない端末では、問い合わせをやめた後の状態になるため、2行目は0を返さず、3行目はunknownになる可能性があります。回避策を入れた状態でも同じ見え方になります。つまり、この2つの値は「Desktopの端末が未対応なのか、フラグで止めたのか」を区別する材料にはなりません。区別したいときはstatus featuresでquery-termの行を見るのが確実です。
同じ症状に見える別の問題との切り分け
端末が応答しないだけで症状が出るため、似た見え方の別件と混ざりやすい点があります。
| 見え方 | 疑う方向 |
|---|---|
| 開いた直後に10秒止まり、上の警告が出る | 疑う方向DA1の無応答(本記事) |
claude: command not found | 疑う方向PATH設定。fishのPATH設定の話 |
| 端末名やDA1の返事が画面にそのまま出る | 疑う方向返事を誰も消費していない別の不具合。iTerm2などの返事の取りこぼしに近い |
| 内蔵ターミナル自体が開かない・落ちる | 疑う方向DA1とは別の原因 |
本記事の症状は逆向きで、問い合わせへの返事が返ってこない側の話です。返事が余って画面に出る側ではありません。警告文にPrimary Device Attributeの語があれば、本記事の症状と見て差し支えありません。
修正の見通しと、待つ間の使い方
このissueは起票が2026年8月21日で、オープンのまま、コメントは0件、staleラベルが付いています。bug・platform:macos・area:desktopのラベルは付いていますが、修正予定や対応バージョンはissueに書かれていません。
Desktopだけでfishを使うのをやめる必要はありません。待ち時間を許容するか、回避策で端末機能の検出ごと止めるか、どちらを取るかの問題です。fishを他の端末でも使うなら、副作用が全端末に及ぶ回避策より、待ち時間を受け入れるほうが影響は小さく済みます。逆に、fishはDesktopでしか使わないなら、回避策の副作用は実質ほとんど出ません。
Desktopアプリそのものの使い方はClaude Desktopの完全ガイドにあります。
よくある質問
Desktop以外のターミナルでも10秒止まりますか
報告されているのはDesktopの内蔵ターミナルだけです。DA1に答える端末では、fishは待たずに起動します。
fishのバージョンを確認するには
次のコマンドで確認できます。報告では4.1以降が対象とされています。
fish --versionClaude Codeの動作にも影響しますか
報告に、claudeの実行や応答が遅くなるという記述はありません。待たされるのはfishの起動時だけです。