Skip to content

fix(anthropic): repair Claude subscription login (moved OAuth endpoints + Cloudflare UA)#702

Merged
ericleepi314 merged 1 commit into
mainfrom
fix/claude-oauth-endpoints
Jul 12, 2026
Merged

fix(anthropic): repair Claude subscription login (moved OAuth endpoints + Cloudflare UA)#702
ericleepi314 merged 1 commit into
mainfrom
fix/claude-oauth-endpoints

Conversation

@ericleepi314

Copy link
Copy Markdown
Collaborator

Summary

The interactive clawcodex login → anthropic → subscription flow failed for a real user at the token-exchange step:

Claude subscription login failed: Claude OAuth request failed (403): error code: 1010

error code: 1010 is a Cloudflare bot block, not an OAuth error — the request never reached Anthropic. The Claude subscription OAuth (added in #697, ported from opencode) was only ever exercised via an imported token; the actual login endpoints were never hit until now. Live diagnosis found two root causes:

1. Stale token endpoint

The login flow migrated off console.anthropic.com to platform.claude.com (authoritative: the in-repo upstream typescript/src/constants/oauth.ts PROD_OAUTH_CONFIG). The old console.anthropic.com/v1/oauth/token now 404s behind Cloudflare. Updated:

  • TOKEN_URLhttps://platform.claude.com/v1/oauth/token
  • REDIRECT_URIhttps://platform.claude.com/oauth/code/callback (the manual copy/paste redirect)
  • SCOPES → the full ALL_OAUTH_SCOPES the real CLI requests (adds user:sessions:claude_code, user:mcp_servers, user:file_upload)
  • AUTHORIZE_URLhttps://claude.com/cai/oauth/authorize — the subscriber entrypoint. A default claude login sets loginWithClaudeAi = !useConsole = true (cli/handlers/auth.ts:133-135); it 307-redirects to claude.ai/oauth/authorize, the consent page a Pro/Max user signs in against. (platform.claude.com/oauth/authorize is the --console/API-account path, which a pure subscriber may not complete.)

2. Missing User-Agent → Cloudflare 1010

urllib defaults to Python-urllib/x.y, whose signature Cloudflare bot-blocks with error code: 1010. The real CLI reaches the endpoint via axios (which sends its own UA); any genuine UA passes. _post_json now sends the same claude-cli User-Agent the inference path uses (and subscription_headers points at the shared constant).

CLIENT_ID is unchanged (it already matched upstream).

Validation

Verified live against the real endpoints (I can't drive the browser consent step autonomously, but every reachable hop is confirmed):

  • bare urllib403 error code: 1010 (reproduces the user's failure)
  • after the fix, complete_login() reaches OAuth: a fake code returns {"error":"invalid_grant","error_description":"Invalid 'code' in request."} — the correct rejection, proving the request now gets through
  • authorize URL claude.com/cai/oauth/authorize307claude.ai/oauth/authorize (the exact consent page the user's original attempt already authorized against — it only died at the dead token host)
  • token endpoint returns invalid_grant, not redirect_uri_mismatch, confirming the authorize/redirect/token triple is a consistent registered combo

Regression tests pin the platform.claude.com token endpoint, the subscriber authorize base, and the load-bearing User-Agent. Full suite: 8486 passed, 3 skipped. Critic-reviewed: APPROVE (verified the authorize-URL correction and the refresh-scope / UA / redirect-consistency questions).

Note

src/auth/oauth.py's separate OAuthFlow (API-key creation, unrelated to subscription login) still references the old console.anthropic.com hosts — flagged for a separate follow-up, not in scope here.

🤖 Generated with Claude Code

…loudflare UA)

The interactive 'clawcodex login -> anthropic -> subscription' flow failed
at token exchange with: 'Claude OAuth request failed (403): error code:
1010'. Root causes, both surfaced only by a real login (the request path
was tested via an imported token; the login endpoints never were):

1. STALE TOKEN ENDPOINT. The token exchange migrated off
   console.anthropic.com to platform.claude.com (upstream
   typescript/src/constants/oauth.ts PROD_OAUTH_CONFIG). The old console
   endpoint now 404s behind Cloudflare. Updated TOKEN_URL + the manual
   REDIRECT_URI to platform.claude.com, and SCOPES to the full
   ALL_OAUTH_SCOPES set the real CLI requests (adds
   user:sessions:claude_code, user:mcp_servers, user:file_upload).

2. MISSING USER-AGENT = Cloudflare 1010. urllib defaults to
   'Python-urllib/x.y', which Cloudflare bot-blocks with 'error code:
   1010' before the request reaches OAuth. The real CLI uses axios (its
   own UA); any genuine UA passes. _post_json now sends the same
   claude-cli UA the inference path uses.

Also corrected AUTHORIZE_URL to the Claude.ai *subscriber* entrypoint
claude.com/cai/oauth/authorize (307 -> claude.ai/oauth/authorize, the
consent page a Pro/Max user signs in against). A default 'claude login'
uses loginWithClaudeAi=!useConsole=true (cli/handlers/auth.ts:133-135);
platform.claude.com/oauth/authorize is the --console/API-account path a
pure subscriber may not complete.

Verified live against the real endpoints: authorize URL 307s to
claude.ai consent; complete_login() reaches OAuth (fake code ->
invalid_grant); bare urllib -> 1010, with UA -> the app. CLIENT_ID
unchanged. Regression tests pin the platform.claude.com token endpoint,
the subscriber authorize base, and the load-bearing User-Agent.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@ericleepi314 ericleepi314 merged commit d48a09b into main Jul 12, 2026
2 checks passed
@ericleepi314 ericleepi314 deleted the fix/claude-oauth-endpoints branch July 12, 2026 22:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant