朝から夕方にかけて、環境周辺で3つのトラブルが連続して起きた。Claude Code のフック音声が鳴らない、Codex で GPT-5.5 が選べない、compress_for_x.py の NVENC エンコードが落ちる。どれも「動いていたものが急に止まる」系で、原因はそれぞれ別の場所にあった。順番に切り分けていった記録を残しておく。
1. Claude Code のフック音声が鳴らない
症状
Claude Code 2.1.x が落ちてきてからネイティブバイナリに切り替わったタイミングで、応答完了時の音声フックが無音になった。Stop hook 自体は走っているのに、スピーカーから何も出てこない。
切り分け
最初は「ネイティブバイナリ化でフック仕様が変わったか?」と疑った。settings.json の hooks.Stop を眺めて、コマンドが変わっていないか確認する。
- フックの定義は前と同じ
- ログを見ると Stop hook 自体は呼ばれている
- VOICEVOX の API 直叩きはターミナルから手動で叩くと普通に鳴る
ここで「フックは壊れていない、その先で死んでいる」と気付いた。フック → sound-server.py → VOICEVOX の3段構成のうち、真ん中が落ちている可能性が高い。
# localhost:50055 で待ち受けているはずのサーバーに ping
curl http://localhost:50055/health
# → 接続拒否
サーバーが死んでいた。
原因
スタートアップフォルダに置いてある claude-sound.bat から sound-server.py を起動する設計になっていた。朝、別作業のために PowerShell ウィンドウを閉じた拍子に、子プロセスとして紐付いていた sound-server.py も道連れで終了していた。
なぜサーバー経由なのかも、ついでに思い出した。WSL から呼ぶときも Windows ネイティブから呼ぶときも、同じエンドポイント localhost:50055 を叩けば音が鳴るようにするためだった。フックから直接 VOICEVOX を叩く実装にすると、WSL 側からのアクセスでハマる。
対処
スタートアップに置いてある claude-sound.bat をダブルクリックして sound-server.py を起動し直しただけで復旧した。Claude Code 2.1.x のネイティブ化は無関係で、たまたま同じタイミングで PowerShell を閉じていた、というだけの話だった。
教訓としては、サーバー経由のフックは「シェルを閉じると死ぬ」というリスクをもつ。タスクスケジューラから独立プロセスとして起動する形に変えるか、起動時に常駐サービス化するか、どちらかに寄せたほうがいい。今日は応急処置だけで終わらせた。
2. Codex CLI で GPT-5.5 が使えない
症状
codex の TUI を開くとモデル選択リストに gpt-5.5 が並んでいる。選択して実行すると、リクエスト送信時に以下のメッセージが流れる。
Model metadata for gpt-5.5 not found. Defaulting to fallback metadata.
そのまま投げると、レスポンスは返ってくるものの、明らかに 5.4 の挙動に見える。コンテキスト長も 5.5 で謳われている値より短い。
切り分け
最初は CLI 側のバージョンを疑った。
codex --versionで最新版になっていることを確認~/.codex/config.tomlのmodel = "gpt-5.5"も問題なし- TUI の表示と実際のメタデータが食い違っているのが奇妙
ここで OpenAI のステータスページとロールアウト情報を確認したら、GPT-5.5 のアカウント単位のロールアウトはまだ全員には届いていないと書いてあった。TUI のモデルリストは「将来選べるかも」を含めて表示している一方で、API メタデータの取得は実際のアカウント権限に依存しているらしい。
つまり「CLI には見えるが、自分のアカウントではまだ叩けない」状態。フォールバック先のメタデータが当たって 5.4 相当で動いていた、ということになる。
対処
config.toml のデフォルトモデルを gpt-5.4 に戻した。
# ~/.codex/config.toml
model = "gpt-5.4"
ロールアウトが届いたら戻す。GPT-5.5 が TUI に表示される ≠ 自分のアカウントで使える、というのは覚えておいたほうがよさそうだ。Model metadata ... not found. Defaulting to fallback metadata のメッセージは、「選んだモデルでは動いていない」サインとして次回からすぐに気付ける。
3. ffmpeg NVENC で unsupported param (12) エラー
症状
compress_for_x.py を走らせると、ffmpeg のサブプロセスが以下のメッセージを吐いて落ちる。
[h264_nvenc @ ...] Provided parameter is unsupported (12)
[h264_nvenc @ ...] No NVENC capable devices found
Error initializing output stream 0:0 -- Error while opening encoder
X 投稿用の動画圧縮が止まり、その日のショート素材を流せなくなっていた。
切り分け
「No NVENC capable devices found」と出ているので最初はドライバを疑った。
nvidia-smiを叩く → GPU は認識されている。CUDA バージョンも上がったばかり- 同じマシンで OBS の NVENC エンコードは普通に通る
- ffmpeg 単体で
ffmpeg -encoders | grep nvencを叩くとh264_nvencもhevc_nvencも並んでいる
つまり「NVENC は生きている、Python から叩いている ffmpeg コマンドラインの引数が腐っている」と推定できる。
compress_for_x.py:70 付近の組み立て部分を読みに行くと、-rc vbr_hq の指定が残っていた。
原因
vbr_hq は NVIDIA Video Codec SDK 9 までの旧プリセット名で、SDK 10 以降は廃止されている。ドライバとともに SDK が更新されたタイミングで、ffmpeg がこの値を受け取った瞬間に「unsupported param」を返すようになっていた。No NVENC capable devices found のメッセージは結果としての副次エラーで、本質は引数のリジェクトだった。
対処
compress_for_x.py:70 の組み立てを書き換える。
# Before(SDK 9 までの旧プリセット)
"-rc", "vbr_hq",
"-cq", "23",
# After(SDK 10 以降)
"-rc:v", "vbr",
"-cq:v", "23",
-rc:v vbr でレート制御を VBR にし、-cq:v 23 で品質ターゲットを指定する。実行し直すと、NVENC が即座に走り出して 1080p の素材が数秒で圧縮された。
エラーメッセージの「No NVENC capable devices found」に引っ張られると、ドライバや GPU の故障を疑って延々と nvidia-smi の出力を眺めることになる。実際には1段手前の引数パースで死んでいて、ドライバは無罪だった。NVENC 系のエラーが出たら、まず ffmpeg の引数をドキュメント最新版と突き合わせる、という順番にしたい。
振り返り
3つとも症状が違う割に、切り分けのパターンは似ていた。
- 表面のエラーメッセージは結果であって原因ではない
- 「動いていたものが止まった」ときは、自分の最近の変更ではなく周辺のバージョンアップを疑う
- フック音声は Claude Code 2.1.x のネイティブ化、GPT-5.5 はロールアウト進捗、NVENC は SDK 10 への更新。どれも自分が触っていない場所が動いていた
切り分けで一番効いたのは、「フックは壊れていない、サーバーが死んでいる」「NVENC は生きている、引数が腐っている」のように、生きている層と死んでいる層を分けて言語化すること。ここを口に出した瞬間、調べる場所が一気に絞れる。
明日やること:
-
sound-server.pyをタスクスケジューラ経由で起動する形に変える(PowerShell を閉じても道連れにならないように) -
compress_for_x.pyのエンコーダ引数を NVIDIA Video Codec SDK 公式ドキュメントの最新リファレンスと突き合わせて、他にも廃止オプションが残っていないか確認する - GPT-5.5 のロールアウト到達を週1で確認する手順を
.claude/issues/にメモしておく