#18311 · @jorgitin02 · opened Mar 20, 2026 at 12:04 AM UTC · last updated Mar 21, 2026 at 1:00 AM UTC
fix: skip Anthropic cache control for OAuth
Score breakdown
Impact
Clarity
Urgency
Ease Of Review
Guidelines
Readiness
Size
Trust
Traction
Summary
This PR fixes a critical bug where Anthropic OAuth requests fail due to unaccepted cache control metadata, rendering Claude models unusable for these users. The fix is narrowly scoped to skip the problematic metadata for OAuth paths and includes dedicated regression tests. This is an urgent fix for a significant user-facing breakage.
Description
Issue for this PR
Closes #17910
Type of change
- [x] Bug fix
- [ ] New feature
- [ ] Refactor / code improvement
- [ ] Documentation
What does this PR do?
Anthropic OAuth requests were still going through the normal Anthropic cache-control path, which adds cache_control: { type: "ephemeral" } to recent prompt messages. That metadata is rejected on the OAuth path and causes the request to fail.
This changes ProviderTransform.message() to skip Anthropic cache-control injection when the resolved auth type is oauth, and updates LLM.stream() to pass the resolved auth type into that transform. I also added regression coverage at two levels: one focused transform test for the cache-control behavior, and one LLM.stream() test that exercises the Anthropic messages request path with OAuth auth present.
The fix is narrow on purpose: it only changes Anthropic when auth is OAuth, and leaves the existing non-OAuth Anthropic caching behavior in place.
How did you verify your code works?
bun test test/session/llm.test.tsbun test test/provider/transform.test.tsbun typecheckbun test
Screenshots / recordings
N/A
Checklist
- [x] I have tested my changes locally
- [x] I have not included unrelated changes in this PR
Linked Issues
#17910 bug: OAuth auth + cache_control ephemeral causes HTTP 400 on all Claude models since 2026-03-17
View issueComments
PR comments
jwcrystal
⚠️ Update: The
cache_controlhypothesis has been disproven. See issue comment for details.
The actual root cause is missing x-anthropic-billing-header that Anthropic now requires for OAuth requests. This PR's approach may not fully resolve the issue.
A reference implementation is available at clewdr@a4e5df3.
jorgitin02
Updated this PR.
It now does three things for Anthropic OAuth:
- skips injected
cache_control - prepends the Claude Code-style billing header system text
- sends the Claude Code user-agent on OAuth requests
Local verification:
bun test ./test/provider/transform.test.tsbun test ./test/session/llm.test.tsbun typecheck
The earlier failing e2e checks were in the app workspace-routing suite, not this provider/session codepath, so those need to be re-evaluated on the refreshed branch checks.
Changed Files
packages/opencode/src/provider/transform.ts
+35−2packages/opencode/src/session/llm.ts
+8−1packages/opencode/test/provider/transform.test.ts
+58−0packages/opencode/test/session/llm.test.ts
+125−0