Summary
When the Anthropic API key is an OAuth token (sk-ant-oat-*), requests fail with HTTP 401 if context-1m-2025-08-07 is configured via model-level headers rather than via agent extra params (context1m: true). The oauth-2025-04-20 beta header is never injected, causing Anthropic to reject the Bearer auth.
Environment
- OpenClaw version: 2026.3.8
- Token type:
sk-ant-oat01-* (OAuth access token)
- Models affected: All Anthropic models (claude-opus-4-6, claude-sonnet-4-6, claude-haiku-4-5)
Error
HTTP 401 authentication_error: OAuth authentication is currently not supported.
(request_id: req_011CYtB1FECiDsgW7yYg9Gms)
The error is misleading — OAuth IS supported, but requires the oauth-2025-04-20 beta header.
Root Cause Analysis
The fix from #19789 correctly handles OAuth tokens inside createAnthropicBetaHeadersWrapper, but this wrapper is only applied when resolveAnthropicBetas() returns a non-empty array:
// pi-embedded-runner/anthropic-stream-wrappers.ts
function resolveAnthropicBetas(extraParams, provider, modelId) {
if (provider !== "anthropic") return;
const betas = new Set();
// Only adds betas from extraParams.anthropicBeta or extraParams.context1m
// ...
return betas.size > 0 ? [...betas] : void 0; // <-- returns undefined
}
const anthropicBetas = resolveAnthropicBetas(merged, provider, modelId);
if (anthropicBetas?.length) {
// This wrapper is NEVER applied when resolveAnthropicBetas returns undefined
agent.streamFn = createAnthropicBetaHeadersWrapper(agent.streamFn, anthropicBetas);
}
If context-1m is configured via the model provider definition (models.providers.anthropic.models[].headers):
{
"id": "claude-opus-4-6",
"headers": { "anthropic-beta": "context-1m-2025-08-07" }
}
...instead of via agent extra params (agents.defaults.models[].params.context1m: true), then:
resolveAnthropicBetas() returns undefined (no extraParams match)
createAnthropicBetaHeadersWrapper is never applied
- The
oauth-2025-04-20 beta is never injected
- The pi-ai SDK detects
sk-ant-oat → uses Authorization: Bearer
- Model-level
headers with anthropic-beta: context-1m-2025-08-07 overwrite the SDK's default headers via Object.assign, stripping the OAuth beta
- Anthropic rejects: "OAuth authentication is currently not supported"
Reproduction
Confirmed via direct curl from the container:
# Works - x-api-key header (bypasses OAuth entirely)
curl -H "x-api-key: $ANTHROPIC_API_KEY" ... → 200 OK
# Works - Bearer auth WITH oauth beta
curl -H "Authorization: Bearer $ANTHROPIC_API_KEY" \
-H "anthropic-beta: oauth-2025-04-20" ... → 200 OK
# Fails - Bearer auth WITHOUT oauth beta (what OpenClaw sends)
curl -H "Authorization: Bearer $ANTHROPIC_API_KEY" ... → 401
Suggested Fix
The oauth-2025-04-20 beta should be injected unconditionally whenever an sk-ant-oat token is detected, not only when createAnthropicBetaHeadersWrapper happens to be applied. The OAuth beta injection should be independent of resolveAnthropicBetas.
Either:
- Always apply
createAnthropicBetaHeadersWrapper for Anthropic providers (even with empty betas), so the OAuth detection logic always runs
- Or add a separate unconditional check for OAuth tokens that injects
oauth-2025-04-20 regardless of other beta configuration
Workaround
Move context-1m from model-level headers to agent extra params:
// Remove from models.providers.anthropic.models[].headers
// Add to agents.defaults.models:
"anthropic/claude-opus-4-6": {
"params": { "context1m": true, "cacheRetention": "short" }
}
Related
🤖 Generated with Claude Code
Summary
When the Anthropic API key is an OAuth token (
sk-ant-oat-*), requests fail with HTTP 401 ifcontext-1m-2025-08-07is configured via model-level headers rather than via agent extra params (context1m: true). Theoauth-2025-04-20beta header is never injected, causing Anthropic to reject the Bearer auth.Environment
sk-ant-oat01-*(OAuth access token)Error
The error is misleading — OAuth IS supported, but requires the
oauth-2025-04-20beta header.Root Cause Analysis
The fix from #19789 correctly handles OAuth tokens inside
createAnthropicBetaHeadersWrapper, but this wrapper is only applied whenresolveAnthropicBetas()returns a non-empty array:If
context-1mis configured via the model provider definition (models.providers.anthropic.models[].headers):{ "id": "claude-opus-4-6", "headers": { "anthropic-beta": "context-1m-2025-08-07" } }...instead of via agent extra params (
agents.defaults.models[].params.context1m: true), then:resolveAnthropicBetas()returnsundefined(no extraParams match)createAnthropicBetaHeadersWrapperis never appliedoauth-2025-04-20beta is never injectedsk-ant-oat→ usesAuthorization: Bearerheaderswithanthropic-beta: context-1m-2025-08-07overwrite the SDK's default headers viaObject.assign, stripping the OAuth betaReproduction
Confirmed via direct curl from the container:
Suggested Fix
The
oauth-2025-04-20beta should be injected unconditionally whenever ansk-ant-oattoken is detected, not only whencreateAnthropicBetaHeadersWrapperhappens to be applied. The OAuth beta injection should be independent ofresolveAnthropicBetas.Either:
createAnthropicBetaHeadersWrapperfor Anthropic providers (even with empty betas), so the OAuth detection logic always runsoauth-2025-04-20regardless of other beta configurationWorkaround
Move
context-1mfrom model-level headers to agent extra params:Related
🤖 Generated with Claude Code