Repository navigation
fix(proxy): direct-connection fallback for control-plane ops when a pinned proxy is unreachable - #3906
Conversation
… proxy is unreachable A dead proxy pinned to an account (via proxy_assignments) made account linking fail with a generic "Internal server error". The OAuth code/token exchange and the connection test run inside runWithProxyContext, whose T14 fast-fail throws PROXY_UNREACHABLE (503) when the pinned proxy can't be reached — with no fallback. Free-proxy pools go stale, so a single dead egress silently breaks linking a new account even though the upstream is reachable directly. - runWithProxyContext gains an opt-in `directFallbackOnUnreachable`: when the reachability/family pre-check fails, it logs a warning and runs the callback with the proxy context cleared (direct egress) instead of throwing. - New runWithProxyContextOrDirect wrapper applies it. - Wire it into the control-plane flows — OAuth (device code / token exchange / refresh) and the provider connection test (validate) — where reaching the upstream matters more than per-account egress-IP pinning. Data-plane chat keeps strict pinning via runWithProxyContext, so IP isolation is preserved. Tests: proxy-fetch.test.ts covers throw-by-default, opt-in fallback, and the wrapper degrading to direct. eslint + typecheck:core clean. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Code Review
This pull request introduces a fallback mechanism to direct connections when a proxy is unreachable or fails family pre-checks. It adds a new helper function runWithProxyContextOrDirect and updates control-plane operations, such as OAuth actions and provider API key validation, to use this fallback instead of throwing a 500 error. Additionally, unit tests have been added to verify this fallback behavior. I have no feedback to provide as there are no review comments.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
…control-plane-direct-fallback
PR cheaper-inference#3906 own growth: oauth/[provider]/[action]/route.ts 916->918 (+2). Updates the frozen file-size baseline so Fast Quality Gates pass. Co-authored-by: diegosouzapw <diegosouza.pw@gmail.com>
|
Thanks, @zhiru! 🙏 The control-plane / data-plane split is exactly right — OAuth code/token exchange, connection tests, and token refresh shouldn't surface a dead pinned proxy as an opaque 500, while chat keeps strict per-account egress-IP pinning. The |
9d846f3
into
cheaper-inference:release/v3.8.26
…inned proxy is unreachable (cheaper-inference#3906) Integrated into release/v3.8.26
Problem
Linking a Claude (OAuth) account can fail with a generic "Internal server error" when the account is pinned to a proxy (
proxy_assignments) that has gone dead. The OAuth code/token exchange and the provider connection test both run insiderunWithProxyContext, whose T14 fast-fail throwsPROXY_UNREACHABLE(503) when the pinned proxy can't be reached — with no fallback. Free-proxy pools go stale quickly, so a single dead egress silently breaks linking a new account, even though the upstream is reachable directly.Observed in production logs:
Fix
Make control-plane operations degrade to a direct connection instead of throwing when the pinned proxy is unreachable:
runWithProxyContextgains an opt-indirectFallbackOnUnreachable. When the reachability check (or the?familypre-check) fails, it logs a warning and runs the callback with the proxy context cleared (proxyContext.run(null, fn)→ direct egress) instead of throwing.runWithProxyContextOrDirect(proxyConfig, fn)wrapper applies it./api/oauth/[provider]/[action])/api/providers/validate)Data-plane chat keeps strict pinning via the unchanged
runWithProxyContext, so per-account egress-IP isolation is preserved where it matters. Control-plane reachability is prioritized over IP pinning — a dead pinned proxy must not block linking/validating an account.Verification
tests/unit/proxy-fetch.test.ts: throw-by-default on an unreachable proxy, opt-in fallback runs the callback directly, andrunWithProxyContextOrDirectdegrades to direct.node --testgreen.eslint+typecheck:coreclean.🤖 Generated with Claude Code