opencode: refresh Databricks token via loopback proxy (fixes ~1h mid-session 401s) - #337
Open
kishor-rkrishnan wants to merge 1 commit into
Open
Conversation
rohita5l
requested changes
Aug 14, 2026
| @@ -1 +1 @@ | |||
| """Loopback refresh proxy for relayed Anthropic (Claude Max/Team/Enterprise). | |||
Collaborator
There was a problem hiding this comment.
Instead of reusing this proxy which is meant for a different provider, can you please create an opencode specific proxy
Author
There was a problem hiding this comment.
Done — moved this into a dedicated opencode_proxy module, so gateway_proxy is now untouched (identical to main). The new proxy is purpose-built for OpenCode (swaps the Authorization header, forwards to the workspace host). Thanks for the review!
…fix ~1h mid-session auth failures OpenCode resolves opencode.json once at process start and never re-reads it, so the Databricks OAuth token baked into the config (the Authorization header) goes stale at the ~1h OAuth token lifetime and every request then fails with 401 Invalid Token, killing long-running sessions. The background thread that rewrites the config every 30 min does not help, because the running process ignores the file after launch. Add a dedicated OpenCode loopback proxy (opencode_proxy) rather than extending the relayed-Anthropic proxy, which is provider-specific. ucode opencode points each provider's baseURL at it; the proxy overwrites the Authorization header with a freshly-minted token on every request via its own background refresher, so the token never goes stale mid-session. One proxy serves all providers since they share the workspace host. The obsolete per-launch file-rewrite refresher is removed. Tests: unit coverage for the proxy's Authorization swap + workspace-root forwarding, and the loopback URL rewrite.
kishor-rkrishnan
force-pushed
the
fix/opencode-token-refresh-proxy
branch
from
August 14, 2026 17:33
8aa819b to
9947ddd
Compare
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.
Problem
Long-running
ucode opencodesessions fail roughly every hour with401 Invalid Tokenand cannot recover without a restart. This is the OpenCode side of #190.Root cause
ucode opencodewrites the Databricks OAuth token intoopencode.json(the providerAuthorizationheader +apiKey). OpenCode resolves that config once at process start and never re-reads it, so when the token reaches its ~1h OAuth lifetime every subsequent request 401s. The existing background thread (_refresh_forever) rewritesopencode.jsonevery 30 min, but the running OpenCode process ignores the file after launch, so the rewrite has no effect.(
ucode claudeis unaffected — it uses Claude Code'sapiKeyHelper, which re-fetches the token on a 401.)Fix
Reuse the loopback refresh proxy already used for relayed Claude (
gateway_proxy): point each OpenCode provider'sbaseURLat the proxy, which overwrites theAuthorizationheader with a freshly-minted token on every request via its own background_TokenCacherefresher. The token written intoopencode.jsonbecomes a bootstrap value the proxy replaces per request, so it never goes stale mid-session.Authorizationand forwards the path unchanged.start_proxygainsupstream_baseandswap_headerkeyword arguments; their defaults reproduce the existing relayed-Claude behavior exactly (the unchanged header tests still pass), so this is purely additive for the Claude path._refresh_forever) is removed.Scoped to this single behavior (the static-token mid-session death). The separate concurrent-refresh token-rotation race (#190 / #197) is intentionally out of scope here.
Testing
uv run pytest— unit suite passes (the only failures are pre-existing environment/e2e ones unrelated to this change).uv run ruff check .andruff format --check .— clean.test_gateway_proxy.py); loopback URL rewrite (test_agent_opencode.py).opencodebinary: with an expired token in the config, requests sent straight to the gateway return 401 (bug reproduced); the same expired-token config pointed at the proxy returns 200 (fixed). Also confirmed the gateway authenticates onAuthorizationand tolerates the stalex-api-keyOpenCode still sends, so swappingAuthorizationalone is sufficient.