[BUG] OAuth messages.create returns 400 for Sonnet/Opus 4 models but works for Haiku 4.5

Resolved 💬 2 comments Opened Mar 18, 2026 by nickmeinhold Closed Mar 21, 2026

Bug Description

OAuth bearer tokens (Max plan) return 400 invalid_request_error "Error" for all Claude 4 Sonnet and Opus models, while Haiku 4.5 works fine with the exact same token and request format.

This has been broken since ~March 16, 2026. Claude Code itself is unaffected (presumably due to internal routing/session handling), but third-party apps using the same OAuth client_id and PKCE flow are stuck on Haiku.

Models Tested (same token, same request)

| Model | Result |
|-------|--------|
| claude-sonnet-4-6 | ❌ 400 {"type":"invalid_request_error","message":"Error"} |
| claude-sonnet-4-20250514 | ❌ 400 {"type":"invalid_request_error","message":"Error"} |
| claude-opus-4-6 | ❌ 400 {"type":"invalid_request_error","message":"Error"} |
| claude-opus-4-20250514 | ❌ 400 {"type":"invalid_request_error","message":"Error"} |
| claude-haiku-4-5-20251001 | ✅ 200 — works perfectly |
| claude-3-haiku-20240307 | ✅ 200 — works perfectly |

Reproduction

Any POST /v1/messages call to api.anthropic.com with:

  • Valid OAuth access token (sk-ant-oat01-*) obtained via refresh from platform.claude.com/v1/oauth/token
  • Header: anthropic-beta: oauth-2025-04-20
  • Header: anthropic-version: 2023-06-01
  • A Sonnet or Opus model ID

Returns 400 with the unhelpful message "Error" (no details).

Switching only the model to Haiku with everything else identical → 200 success.

We also tested:

  • Raw fetch() vs Anthropic SDK (@anthropic-ai/sdk 0.79.0) — same result
  • Streaming vs non-streaming — same result
  • With/without metadata.user_id — same result
  • With/without x-app: cli header — same result
  • From local machine vs GCP server — same result
  • client.beta.messages.create with betas body param — same result

Environment

  • @anthropic-ai/sdk: 0.79.0
  • Node.js: 22.22.1
  • OAuth client_id: 9d1c250a-e61b-44d9-88ed-5944d1962f5e (Claude Code CLI)
  • Token endpoint: https://platform.claude.com/v1/oauth/token
  • Subscription: Max plan (20x rate limit tier)
  • Token scopes: user:inference user:profile user:mcp_servers user:sessions:claude_code user:file_upload

Impact

We're a small nonprofit running a Telegram bot (gremlin) that uses Claude as an AI agent with 66+ MCP tools. We use the same OAuth flow and client_id as Claude Code to authenticate against our Max plan subscription.

Since March 16, we've been forced to downgrade from Sonnet to Haiku 4.5, which significantly degrades the bot's capability for complex multi-tool agent tasks. We can't afford separate API credits on top of the Max subscription.

Expected Behavior

All models available on the Max plan should work with OAuth bearer tokens, not just Haiku.

Related

  • Anthropic status page incident: "Elevated errors on Claude Sonnet 4.6" (marked resolved, but OAuth callers are still affected)
  • #10719 — Similar OAuth 400 error for Pro subscription
  • #13770 — anthropic-beta header rejects oauth-2025-04-20

View original on GitHub ↗

This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗