{"record":{"id":"7ca0055a7de79c2f","repo":"router-for-me/CLIProxyAPI","slug":"pkce-codes-are-required-for-token-exchange","errorCode":null,"errorMessage":"PKCE codes are required for token exchange","messagePattern":"PKCE codes are required for token exchange","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/auth/claude/anthropic_auth.go","lineNumber":372,"sourceCode":"\treturn\n}\n\n// ExchangeCodeForTokens exchanges authorization code for access tokens.\n// This method implements the OAuth2 token exchange flow using PKCE for security.\n// It sends the authorization code along with PKCE verifier to get access and refresh tokens.\n//\n// Parameters:\n//   - ctx: The context for the request\n//   - code: The authorization code received from OAuth callback\n//   - state: The state parameter for verification\n//   - pkceCodes: The PKCE codes for secure verification\n//\n// Returns:\n//   - *ClaudeAuthBundle: The complete authentication bundle with tokens\n//   - error: An error if token exchange fails\nfunc (o *ClaudeAuth) ExchangeCodeForTokens(ctx context.Context, code, state string, pkceCodes *PKCECodes) (*ClaudeAuthBundle, error) {\n\tif pkceCodes == nil {\n\t\treturn nil, fmt.Errorf(\"PKCE codes are required for token exchange\")\n\t}\n\tnewCode, newState := o.parseCodeAndState(code)\n\n\t// Prepare token exchange request. The struct field order reproduces the key\n\t// order Claude Code 2.1.220 emits on the wire; a map would be re-sorted\n\t// alphabetically by encoding/json and change the serialized body bytes.\n\treqBody := authorizationCodeExchangeRequest{\n\t\tGrantType:    \"authorization_code\",\n\t\tCode:         newCode,\n\t\tRedirectURI:  RedirectURI,\n\t\tClientID:     ClientID,\n\t\tCodeVerifier: pkceCodes.CodeVerifier,\n\t\tState:        state,\n\t}\n\n\t// A state fragment appended to the callback code takes precedence.\n\tif newState != \"\" {\n\t\treqBody.State = newState","sourceCodeStart":354,"sourceCodeEnd":390,"githubUrl":"https://github.com/router-for-me/CLIProxyAPI/blob/78f0c4079e3e6273d65d03b5549cffc898703264/internal/auth/claude/anthropic_auth.go#L354-L390","documentation":"Error \"PKCE codes are required for token exchange\" thrown in router-for-me/CLIProxyAPI.","triggerScenarios":"Thrown at internal/auth/claude/anthropic_auth.go:372 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Complete the authorization step first to obtain the code, keeping the generated verifier.","Restart the OAuth flow if the PKCE verifier was lost between authorize and exchange."],"exampleFix":null,"handlingStrategy":null,"validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"78f0c4079e3e6273d65d03b5549cffc898703264","analyzedAt":"2026-08-15T12:26:37.444Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}