fix(anthropic): repair Claude subscription login (moved OAuth endpoints + Cloudflare UA)#702
Merged
Merged
Conversation
…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>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The interactive
clawcodex login → anthropic → subscriptionflow failed for a real user at the token-exchange step:error code: 1010is 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.comtoplatform.claude.com(authoritative: the in-repo upstreamtypescript/src/constants/oauth.tsPROD_OAUTH_CONFIG). The oldconsole.anthropic.com/v1/oauth/tokennow 404s behind Cloudflare. Updated:TOKEN_URL→https://platform.claude.com/v1/oauth/tokenREDIRECT_URI→https://platform.claude.com/oauth/code/callback(the manual copy/paste redirect)SCOPES→ the fullALL_OAUTH_SCOPESthe real CLI requests (addsuser:sessions:claude_code,user:mcp_servers,user:file_upload)AUTHORIZE_URL→https://claude.com/cai/oauth/authorize— the subscriber entrypoint. A defaultclaude loginsetsloginWithClaudeAi = !useConsole = true(cli/handlers/auth.ts:133-135); it 307-redirects toclaude.ai/oauth/authorize, the consent page a Pro/Max user signs in against. (platform.claude.com/oauth/authorizeis the--console/API-account path, which a pure subscriber may not complete.)2. Missing User-Agent → Cloudflare 1010
urllibdefaults toPython-urllib/x.y, whose signature Cloudflare bot-blocks witherror code: 1010. The real CLI reaches the endpoint via axios (which sends its own UA); any genuine UA passes._post_jsonnow sends the sameclaude-cliUser-Agent the inference path uses (andsubscription_headerspoints at the shared constant).CLIENT_IDis 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):
403 error code: 1010(reproduces the user's failure)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 throughclaude.com/cai/oauth/authorize→307→claude.ai/oauth/authorize(the exact consent page the user's original attempt already authorized against — it only died at the dead token host)invalid_grant, notredirect_uri_mismatch, confirming the authorize/redirect/token triple is a consistent registered comboRegression tests pin the
platform.claude.comtoken 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 separateOAuthFlow(API-key creation, unrelated to subscription login) still references the oldconsole.anthropic.comhosts — flagged for a separate follow-up, not in scope here.🤖 Generated with Claude Code