Skip to content

OAuth 401 regression: oauth-2025-04-20 beta not injected when context1m set via model headers #41444

Description

@hnykda

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:

  1. resolveAnthropicBetas() returns undefined (no extraParams match)
  2. createAnthropicBetaHeadersWrapper is never applied
  3. The oauth-2025-04-20 beta is never injected
  4. The pi-ai SDK detects sk-ant-oat → uses Authorization: Bearer
  5. Model-level headers with anthropic-beta: context-1m-2025-08-07 overwrite the SDK's default headers via Object.assign, stripping the OAuth beta
  6. 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:

  1. Always apply createAnthropicBetaHeadersWrapper for Anthropic providers (even with empty betas), so the OAuth detection logic always runs
  2. 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

Metadata

Metadata

Assignees

No one assigned

    Labels

    P1High-priority user-facing bug, regression, or broken workflow.clawsweeper:fix-shape-clearClawSweeper found a clear likely implementation shape for this issue.clawsweeper:linked-pr-openClawSweeper found an open linked pull request for this issue.clawsweeper:needs-maintainer-reviewClawSweeper marked this issue as needing maintainer review before automation.clawsweeper:no-new-fix-prClawSweeper does not recommend queueing a new automated fix PR for this issue.clawsweeper:source-reproClawSweeper found a high-confidence source-level issue reproduction.impact:auth-providerAuth, provider routing, model choice, or SecretRef resolution may break.issue-rating: 🦞 diamond lobsterVery strong issue quality with high-confidence source-level or clear reproduction.staleMarked as stale due to inactivity

    Type

    No type

    Fields

    Priority

    None yet

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions