Repository navigation
fix(launchd): credential-proxy exits 127 when node isn't on the plist PATH - #1894
Merged
Merged
Conversation
jsun-m
force-pushed
the
jm/patch-anthropic-subscription-usage
branch
2 times, most recently
from
July 2, 2026 17:08
1b2124f to
371ace8
Compare
… PATH The launchd-supervised credential proxy (com.sutando.credential-proxy) injects and self-refreshes (#1767) the Claude.ai subscription OAuth for the core (ANTHROPIC_BASE_URL=http://localhost:7846). Its wrapper resolves npx/tsx by absolute path, but those re-exec `node` via `#!/usr/bin/env node`, and launchd runs with only the plist's fixed PATH (a /opt/homebrew/bin:… guess). On an Intel-Homebrew (/usr/local/bin) / nvm / volta install, `env node` fails with "No such file or directory" → the wrapper exits 127 → the proxy never binds :7846 (and KeepAlive's stale-holder eviction kills any manual proxy). The core then hits ConnectionRefused and can't authenticate at all. Resolve exactly one node dir (first match wins) in the same priority order and with the same NEWEST-nvm selection as resolve_npx/resolve_tsx: Homebrew, then `ls ~/.nvm/versions/node | sort -V | tail -1`, then volta. Deliberately NOT a `*/bin` glob — glob order is lexicographic, so a box with v9 + v10 would pick v9 (v10 sorts first, v9 last-wins on prepend), i.e. an older node. Prepend that one dir before exec so the proxy starts regardless of the plist's guess and existing installs self-heal without re-running the installer. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
jsun-m
force-pushed
the
jm/patch-anthropic-subscription-usage
branch
from
July 2, 2026 18:19
371ace8 to
051da7d
Compare
Contributor
|
@cla-assistant check |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes
Standalone fix — no tracking issue. (Related: #1767 credential-proxy OAuth self-refresh; #1291 / #1086 launchd supervision.)
Summary
The launchd-supervised credential proxy (
com.sutando.credential-proxy) exits 127 and never binds:7846on machines wherenodeisn't in the plist's hardcodedPATH.credential-proxy-wrapper.shresolvesnpx/tsxby absolute path, but those re-execnodevia#!/usr/bin/env node, and launchd runs with only the plist'sEnvironmentVariables.PATH(a fixed/opt/homebrew/bin:…guess). On an Intel-Homebrew (/usr/local/bin) / nvm / volta install,env node→No such file or directory→ exit 127 → the proxy never binds:7846(and KeepAlive's stale-holder eviction also kills any manually-started proxy).Because the subscription core routes through this proxy (
ANTHROPIC_BASE_URL=http://localhost:7846) for OAuth injection + token self-refresh (#1767), a dead proxy means every request hits ConnectionRefused — the core can't authenticate at all.Fix: the wrapper prepends the real
nodeinstall dir it finds (checks/usr/local/bin,/opt/homebrew/bin, nvm, volta) toPATHbefore exec, so the proxy starts regardless of the plist's guess and existing installs self-heal without re-running the installer.Test plan
/usr/local/bin;logs/credential-proxy.logshowed repeatedenv: node: No such file or directory,launchctl listshowed last-exit 127, nothing listening on:7846, core showedAPI Error: Unable to connect to API (ConnectionRefused).launchctl kickstart -k gui/$(id -u)/com.sutando.credential-proxy→ proxy binds:7846([Proxy] OAuth token loaded from keychain), core reconnects,[Quota]lines resume (subscriptionanthropic-ratelimit-unified-*headers present), no more ConnectionRefused.bash -n src/launchd/credential-proxy-wrapper.shclean; the PATH-resolution loop verified to locatenodestarting from a strippedPATH=/usr/bin:/bin.Checklist notes
core-config/provider-env.shdependencies also land.)install-credential-proxy-launchd.shto write the correct node dir into the plist so fresh installs don't rely on the wrapper heal.