Found during the round-4 review of #222, which fixed the same class of defect in start-proxy.sh's success note (#224). This one is in the sibling script and is pre-existing on main from #196 / #212 and the upstream work, so it gets its own issue rather than riding that branch.
What happens
When a session's requests are being routed to a proxy that is not answering, check-proxy.sh prints a recovery command for the user to paste (scripts/check-proxy.sh:71-74):
To fix it now, in a terminal (the dashboard flags matter: without them /dashboard/ is a 404, and
this proxy would then hold the port for the whole --idle-exit window with no way to notice why):
context-guru-proxy --listen 127.0.0.1:${PORT} --preset ${CLAUDE_PLUGIN_OPTION_PRESET:-cache} \
--dashboard --dashboard-db "${STATE_DIR}/dashboard-${PORT}.db"
That command does not reproduce the proxy the plugin itself starts. check-proxy.sh contains no mention of UPSTREAM or --config at all (0 matches), while start-proxy.sh passes both. Three configured things are silently dropped:
| Dropped |
start-proxy.sh |
Consequence of pasting the printed command |
--config <keepalive yaml> |
:264-267 |
keep-alive comes back OFF after the user explicitly turned it on. The file exists and is what start-proxy.sh keys on, so the hook-started proxy had it and this one does not. |
--anthropic-upstream |
:248-251 |
the proxy goes straight to api.anthropic.com, bypassing the gateway that holds the credential. plugin.json's own upstream description: "on at least one pod, rewriting model names: bypassing it sends model ids the real API has never heard of and every request fails." |
--idle-exit |
:273 |
the flag defaults to 0 = never exit (cmd/context-guru-proxy/main.go:98), so the pasted proxy runs until killed — the opposite of the idle_exit option's promise that "nothing is left running on your machine". |
And --preset ${CLAUDE_PLUGIN_OPTION_PRESET:-cache} names the plugin option, which is not what is in effect whenever a keep-alive config exists, because --config replaces the preset entirely (loadConfig returns config.Load(path) and never consults preset). That is exactly the misreport #224 fixed for the success note, in the same three lines that also drop the config.
Why it matters more than a wrong string
This text is shown at the one moment the user is already broken and least able to check the plugin's reasoning: requests are hanging with no error. It is presented as "to fix it now", so it will be pasted. The result is a proxy that answers /healthz — so every signal the plugin surfaces afterwards says healthy — while quietly running with a feature the user pays for turned off, and, for anyone behind a gateway, failing every request for a reason nothing in the output points at.
Suggested fix
Build the printed command from the same values start-proxy.sh uses, rather than re-deriving a subset of them: include --config when keepalive-${PORT}.yaml exists, include --anthropic-upstream when an upstream is configured, include --idle-exit, and report the preset actually in effect (the config file's, when one is in play) the way start-proxy.sh now does after #224.
Worth a test in the shape of TestStartProxyReportsThePresetActuallyInEffect: with a keep-alive config and an upstream configured, assert the printed command contains --config and --anthropic-upstream and does not name the option's preset. The two scripts deriving the same launch line independently is the root cause, so a test that pins them together is more valuable than one that pins the string.
Note
Reported by the reviewing session rather than fixed there, per the repo rule about defects on main unrelated to the branch under review. Related: #224 (the same misreport in start-proxy.sh's note) and #223 (per-option fallback discovery, which makes CLAUDE_PLUGIN_OPTION_PRESET legitimately a plugin.json default rather than anything the user set).
Found during the round-4 review of #222, which fixed the same class of defect in
start-proxy.sh's success note (#224). This one is in the sibling script and is pre-existing onmainfrom #196 / #212 and the upstream work, so it gets its own issue rather than riding that branch.What happens
When a session's requests are being routed to a proxy that is not answering,
check-proxy.shprints a recovery command for the user to paste (scripts/check-proxy.sh:71-74):That command does not reproduce the proxy the plugin itself starts.
check-proxy.shcontains no mention ofUPSTREAMor--configat all (0 matches), whilestart-proxy.shpasses both. Three configured things are silently dropped:start-proxy.sh--config <keepalive yaml>:264-267start-proxy.shkeys on, so the hook-started proxy had it and this one does not.--anthropic-upstream:248-251plugin.json's ownupstreamdescription: "on at least one pod, rewriting model names: bypassing it sends model ids the real API has never heard of and every request fails."--idle-exit:2730= never exit (cmd/context-guru-proxy/main.go:98), so the pasted proxy runs until killed — the opposite of theidle_exitoption's promise that "nothing is left running on your machine".And
--preset ${CLAUDE_PLUGIN_OPTION_PRESET:-cache}names the plugin option, which is not what is in effect whenever a keep-alive config exists, because--configreplaces the preset entirely (loadConfigreturnsconfig.Load(path)and never consultspreset). That is exactly the misreport #224 fixed for the success note, in the same three lines that also drop the config.Why it matters more than a wrong string
This text is shown at the one moment the user is already broken and least able to check the plugin's reasoning: requests are hanging with no error. It is presented as "to fix it now", so it will be pasted. The result is a proxy that answers
/healthz— so every signal the plugin surfaces afterwards says healthy — while quietly running with a feature the user pays for turned off, and, for anyone behind a gateway, failing every request for a reason nothing in the output points at.Suggested fix
Build the printed command from the same values
start-proxy.shuses, rather than re-deriving a subset of them: include--configwhenkeepalive-${PORT}.yamlexists, include--anthropic-upstreamwhen an upstream is configured, include--idle-exit, and report the preset actually in effect (the config file's, when one is in play) the waystart-proxy.shnow does after #224.Worth a test in the shape of
TestStartProxyReportsThePresetActuallyInEffect: with a keep-alive config and an upstream configured, assert the printed command contains--configand--anthropic-upstreamand does not name the option's preset. The two scripts deriving the same launch line independently is the root cause, so a test that pins them together is more valuable than one that pins the string.Note
Reported by the reviewing session rather than fixed there, per the repo rule about defects on
mainunrelated to the branch under review. Related: #224 (the same misreport instart-proxy.sh's note) and #223 (per-option fallback discovery, which makesCLAUDE_PLUGIN_OPTION_PRESETlegitimately aplugin.jsondefault rather than anything the user set).