v4.2.1 is a hotfix for a real bug in v4.2.0's proxy-owned OAuth refresh feature (#234). If you enabled CACHE_FIX_OAUTH_REFRESH=on on v4.2.0, upgrade immediately.
npm install -g claude-code-cache-fix@4.2.1The bug
The v4.2.0 refresher hardcoded the refresh-grant scope field to user:inference user:profile. Real Claude Code credentials hold a wider set (typically user:file_upload user:inference user:mcp_servers user:profile user:sessions:claude_code). When the proxy refreshed:
- The server happily issued the narrower token requested
/v1/messagestraffic kept working (only needsuser:inference)- remote-bridge / code-session API calls 401'd because
user:sessions:claude_codewas missing
The failure surfaced as silent OAuth expiry on remote-control sessions specifically. Local CC traffic showed no symptoms throughout the affected window.
The fix
The refresher now reads claudeAiOauth.scopes from the credential file inside the in-lock re-read and serializes those scopes verbatim onto the refresh POST (space-separated per RFC 6749 §3.3). A small fallback set applies only when the credential file has no scopes array (unusual). CACHE_FIX_OAUTH_SCOPE env var is honored as an operator override.
6 new regression tests assert:
- Full-scope round-trip (the bug regression)
user:sessions:claude_codepreservation (the load-bearing scope from the incident)- Persisted-credential scope passthrough
- Env override beats credential file
- Fallback when credential lacks
scopesarray - Dedupe + filter for malformed scope entries
Test count: 17 → 23. All pass.
Who should upgrade
Anyone on v4.2.0 with CACHE_FIX_OAUTH_REFRESH=on — the next proxy-initiated refresh will issue a token that does not work for remote bridges, even though local CC traffic continues normally. Upgrade or set CACHE_FIX_OAUTH_REFRESH=off and bounce the proxy.
If you never enabled the OAuth refresh feature on v4.2.0, this hotfix is informational — you're not affected.
Upgrade
npm install -g claude-code-cache-fix@4.2.1Then restart your proxy (supervisor-level, per v4.0.0's hot-reload-off default):
systemctl --user restart cache-fix-proxy # Linux / systemd
launchctl unload ~/Library/LaunchAgents/com.cnighswonger.cache-fix-proxy.plist && launchctl load ~/Library/LaunchAgents/com.cnighswonger.cache-fix-proxy.plist # macOS / launchdNo env-var changes required. The fix is purely code; existing drop-in configs are preserved.
Post-mortem
The v4.2.0 directive (#236) and implementation (#237) both passed Codex r1+r2 review without anyone catching the scope-narrowing. Lessons:
- v4.2.0 unit tests verified the rotated token landed correctly but never asserted the POST body's scope matched the credential's scope. Adding that assertion would have caught the bug pre-release.
- Binary-forensics gave us the request grammar (field names, endpoint, client_id) but missed that the
scopevalue must mirror the credential'sscopesarray rather than match a code-path-inferred string.