security-guidanceでAppXSvcのメモリが枯渇するWindowsの不具合と回避策
Windowsでsecurity-guidanceのsg-python.shがpy -3を2回起動し、AppXSvcのメモリが増え続ける不具合の仕組みと、プラグイン無効化・Python入れ替えなどの回避策をまとめます。
WindowsでPythonを「Python Install Manager」から入れ、security-guidanceプラグインを有効にしている環境で、システムのコミットメモリが数時間で枯渇する不具合が報告されています。原因はプラグインのランチャーsg-python.shが、フックのたびにWindowsのアプリ実行エイリアスpy -3を2回起動することです。報告はGitHubのissue #98929で、状態はopenです。
報告されている症状と数字
報告者の環境はWindows 11 Pro、Claude Code 2.1.287、security-guidance 2.0.8、Python Install Manager 26.3.240.0です。同じ症状は2.1.278、2.1.280、2.1.281でも出ており、最新版で入った退行ではないとされています。
セッションを5つ開いた状態で、AppX Deployment Service(AppXSvc)の更新イベントが次のように積み上がりました。
報告された更新イベントとメモリ
更新イベント(10/1 18:26〜24:00)
5,980件
起動12時間後のAppXSvc
21.84GB
コミットメモリ
システムのコミット残り
1.2GB
全体101.6GB中
最悪の状態では、搭載RAMが42GB空いていても、新しいプロセスが起動時にOutOfMemoryExceptionで落ちました。コミットメモリ(仮想メモリの予約量)が尽きると、物理メモリに余裕があってもプロセスは作れません。報告者の環境では無関係な.NETサービスとテスト実行も巻き込まれています。
1回の更新あたりの増加量は約1.6MBとハンドル5個です。176回の更新を挟んだ2回の計測で、AppXSvcのプライベートメモリは2.00GBから2.28GBに、ハンドル数は9,237から10,103に増えています。メモリは再起動かサービスの再起動まで戻りません。
なぜフック1回でPythonが2回走るのか
security-guidanceはhooksの上に組まれたプラグインです。issueによると、sg-python.shは次のタイミングで毎回呼ばれます。
- SessionStart
- UserPromptSubmitのたび
Edit|Write|MultiEdit|NotebookEditへのPostToolUse- BashへのPostToolUse
- StopとSubagentStop
呼ばれるたびに、シェルはインタープリタを一から探し直します。python3.13からpython3.10、python3、python、py -3の順に、各候補で-cを付けてバージョンを読む。通った候補をもう一度起動して、本来のフックスクリプトを実行します。
つまり1フックで最低2回、先の候補が落ちればそれ以上Pythonが起動します。この探索順は、プラグインの導入手順にも「versionedなpython3.13〜python3.10を優先し、python3、python、py -3にフォールバックする」と書かれています。仕様どおりの動作です。
起動のたびにAppX更新が走る連鎖
Python Install Managerは、MSIXパッケージPythonSoftwareFoundation.PythonManagerとして入ります。Git Bashから見えるpyは、このパッケージのアプリ実行エイリアス(%LOCALAPPDATA%\Microsoft\WindowsApps\py.exe)です。
報告では、エイリアスを起動するたびにWindowsがApp Installerの更新処理を始めました。AppXDeploymentServerのログにイベント603が1回出ます。更新間隔24時間の設定も、CheckForUpdatesOnLaunch = Falseも無視されたとのことです。
メモリが解放されないのはWindows側の欠陥で、Microsoftへ別途報告済みだと書かれています。Claude Code側の問題になるのは起動頻度です。1フック2回の起動が、セッションの数だけ、プロンプトと編集の数だけ積み重なります。
メモリが減らなくなるまでの流れ
- 1
フックが発火する
プロンプト送信、ファイル編集、ターン終了のどれでも
sg-python.shが走ります。 - 2
py -3 が2回起動する
バージョン確認の1回と、フック本体の実行の1回です。
- 3
AppX更新が2件始まる
イベント603が同じ秒に対で記録されます。
- 4
AppXSvcに約1.6MBが残る
更新のたびに増え、再起動まで戻りません。
自分の環境が該当するか確かめる
該当の条件は、Git BashのpyがWindowsAppsのエイリアスで、それより先にバージョン確認を通るpython3.1x・python3・pythonが無いことです。まずGit Bashで解決先を見ます。
command -v python3.13 python3 python pypyだけがWindowsApps配下を指していれば、報告と同じ経路に入る可能性があります。次にPowerShellで、イベント603が積み上がっていないかを調べます。以下は報告のログ名をもとにした確認例です。
Get-WinEvent -LogName "Microsoft-Windows-AppXDeploymentServer/Operational" `
-MaxEvents 200 | Where-Object Id -eq 603 | Measure-Object数分のうちに大量の件数が出るなら、更新イベントがフックと連動しています。AppXSvcのメモリは、サービスのプロセスIDから読めます。
$p = (Get-CimInstance Win32_Service -Filter "Name='AppXSvc'").ProcessId
Get-Process -Id $p | Select-Object PrivateMemorySize64, HandleCount報告者は、sg-python.shを直接100回叩く再現手順も載せています。Git Bashで同じシェルを繰り返し呼び、イベントビューアで603が1回の起動につき1件ずつ増えるのを確かめる方法です。
回避策の選び方
issueの時点で修正版はありません。取れる手は、プラグイン側を止めるか、Python側を入れ替えるかの2系統です。
| 回避策 | 効き方 | 注意 |
|---|---|---|
/plugin disable security-guidance@claude-plugins-official | 効き方フックが走らなくなり、pyの起動も止まる | 注意脆弱性の自動レビューも止まる |
SECURITY_GUIDANCE_DISABLE=1 | 効き方ドキュメント上はプラグイン全体の無効化 | 注意ランチャーが探索前に抜けるかは記載なし |
| Python Install Managerを消し、標準インストーラーで入れ直す | 効き方報告者が検証済み。22回の起動でイベント0件 | 注意再起動後に確認。他のPython環境へ影響する |
disableAllHooks: true | 効き方全フックが止まる | 注意他のフックも止まるため粗い手段 |
最初の行が、いちばん副作用の見通しやすい方法です。無効化はユーザースコープなら/plugin disable、シェルからならclaude plugin disableで行えます。プロジェクトの設定で有効化されているときは、--scope localで自分だけ無効にできます。管理設定(managed settings)で配布されたプラグインは、管理者しか止められません。
3行目は報告者が確かめた恒久策です。Install Managerを外して標準インストーラーで入れ直し、再起動したあとに同じランチャーを22回走らせても更新イベントは出ず、AppXSvcは0.03GB・683ハンドルのままでした。pyが実体のインタープリタを指すようになるため、エイリアス経由のAppX起動が起きないという理屈です。
disableAllHooksは、設定ファイルに"disableAllHooks": trueを書くと全てのフックを止められます。個別のフックだけを残して止める方法はなく、security-guidance以外のフックも落ちます。1回の起動だけ止めるなら--settings '{"disableAllHooks": true}'を渡せます。
すでにメモリが膨らんだあとは、AppXSvcが自然には縮みません。再起動するか、サービスを再起動して回収します。
関連して報告されている3件の問題
同じランチャーに絡む報告が、プラグインのリポジトリにも出ています。issueは互いに重複ではなく、起動回数を増やす側にも働くとされています。
| issue | 内容 |
|---|---|
| claude-plugins-official #6186 | 内容python3がInstall Managerのエイリアスだと、全フックがENOENTで失敗する |
| claude-plugins-official #6315 | 内容候補の確認に時間制限がなく、応答しないpython3で全フックが止まる |
| claude-code #85163 | 内容Bash呼び出し1回でハンドラが5つ登録され、Pythonも5プロセス走る |
#6186の原因は、エイリアス経由で起動したプロセスがパッケージのIDで動き、AppDataが仮想化されることです。同じインタープリタでも、エイリアス経由だと%APPDATA%\Roaming\Claude配下のフックファイルが見えません。フルパスで起動すると見えます。報告者は、ランチャーがフックスクリプトを実際に読めるかを確認する修正案を出しています。
#6315は、Install Managerのpython3エイリアスが非対話のフック環境で応答せず、各フックがタイムアウトまで待った例です。エイリアスを無効にすると正常に戻ったとあります。ただしこれはpython3の話で、#98929のようにpyだけがPythonに到達できる環境では、pyのエイリアスまで切ると候補が残りません。
報告者が求めている修正
#98929は、設計面の修正を3点挙げています。
- セッション開始時にインタープリタを一度だけ解決し、絶対パスを保存して以降のフックはそのパスを
execする - キャッシュが無いときは、バージョン確認とフック実行を同じ起動で済ませる
- Windowsでは
%LOCALAPPDATA%\Microsoft\WindowsApps配下のエイリアスより、実体のインタープリタを優先する
修正の入る時期は示されていません。issueのコメントは0件で、ラベルはbug・has repro・platform:windows・area:hooks・area:pluginsです。
影響が出る人と出ない人
報告されている条件は、WindowsのGit Bashでフックを動かし、Python Install Managerだけでpyを用意している環境です。標準インストーラーで入れたPythonや、python3.1xが先に答える環境では、エイリアス起動が起きない構成です。
セッションを複数並べるほど、更新イベントは速く積み上がります。報告者の計測では、イベント数がセッション数とフックの発火回数に比例して増えています。
プラグイン自体の機能と設定項目は、security-guidanceの導入手順にまとめています。Windows環境のフック周りでは、Git Bashでコマンドが約8KBで切れる問題も、同じシェル経由の実行で起きる別の症状です。Windowsのメモリ関連の整備はv2.1.47でまとまって入っていますが、今回の原因はClaude Code本体ではなくプラグインのランチャーとWindowsの組み合わせにあります。