{"record":{"id":"4ea73ad90f9283f0","repo":"xtekky/gpt4free","slug":"missing-pkce-verifier-in-state-parameter-4ea73a","errorCode":null,"errorMessage":"Missing PKCE verifier in state parameter","messagePattern":"Missing PKCE verifier in state parameter","errorType":"validation","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"g4f/Provider/needs_auth/GeminiCLI.py","lineNumber":1123,"sourceCode":"            \"scope\": \" \".join(GEMINICLI_SCOPES),\n            \"code_challenge\": challenge,\n            \"code_challenge_method\": \"S256\",\n            \"state\": state,\n            \"access_type\": \"offline\",\n            \"prompt\": \"consent\",\n        }\n\n        url = f\"https://accounts.google.com/o/oauth2/v2/auth?{urlencode(params)}\"\n        return url, verifier, state\n\n    @classmethod\n    async def exchange_code_for_tokens(cls, code: str, state: str) -> Dict[str, Any]:\n        \"\"\"Exchange authorization code for access and refresh tokens.\"\"\"\n        decoded_state = decode_oauth_state(state)\n        verifier = decoded_state.get(\"verifier\", \"\")\n\n        if not verifier:\n            raise RuntimeError(\"Missing PKCE verifier in state parameter\")\n\n        start_time = time.time()\n\n        async with aiohttp.ClientSession() as session:\n            token_data = {\n                \"client_id\": AuthManager.OAUTH_CLIENT_ID,\n                \"client_secret\": AuthManager.OAUTH_CLIENT_SECRET,\n                \"code\": code,\n                \"grant_type\": \"authorization_code\",\n                \"redirect_uri\": GEMINICLI_REDIRECT_URI,\n                \"code_verifier\": verifier,\n            }\n\n            async with session.post(\n                \"https://oauth2.googleapis.com/token\",\n                data=token_data,\n                headers={\"Content-Type\": \"application/x-www-form-urlencoded\"},\n            ) as resp:","sourceCodeStart":1105,"sourceCodeEnd":1141,"githubUrl":"https://github.com/xtekky/gpt4free/blob/973504e1770928ed5fb82f43da528f441ad9ddc3/g4f/Provider/needs_auth/GeminiCLI.py#L1105-L1141","documentation":"During the OAuth authorization-code exchange, the state parameter was decoded but contained no 'verifier' field. The PKCE code_verifier is required by Google's token endpoint, so without it the exchange cannot proceed. It means the state blob was truncated, hand-modified, or produced by a different flow than this one expects.","triggerScenarios":"exchange_code_for_tokens(code, state) is called with a state string that decodes successfully but lacks the PKCE verifier — for example a URL whose state param is from an older attempt or was URL-truncated, or the manual-input path falling back to a user-supplied state.","commonSituations":"User copies only part of the redirect URL; browser or terminal truncates the long state on copy; retrying an old authorization code with a newly generated state; state query param mangled by terminal paste.","solutions":["Restart the login flow and copy the FULL redirect URL, including the complete state query parameter","If pasting a raw code, make sure it comes from the same login attempt that generated the state","Avoid editing or re-wrapping the redirect URL (terminals can insert newlines into long query strings)","If it persists, use the localhost callback-server mode instead of manual copy-paste"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"from g4f.Provider.needs_auth.GeminiCLI import decode_oauth_state\n\ndef state_has_verifier(state: str) -> bool:\n    try:\n        return bool(decode_oauth_state(state).get(\"verifier\"))\n    except Exception:\n        return False\n\nassert state_has_verifier(callback_state), \"state lacks PKCE verifier; restart login\"","typeGuard":null,"tryCatchPattern":"try:\n    tokens = await GeminiCLI.exchange_code_for_tokens(code, state)\nexcept RuntimeError as e:\n    if \"Missing PKCE verifier\" in str(e):\n        url, verifier, state = GeminiCLI.get_auth_url()  # restart flow\n        # prompt the user again with the new URL","preventionTips":["Keep the auth URL and the code/state from the same login attempt","Copy redirect URLs whole; never retype the state parameter","Validate the decoded state before calling the token endpoint"],"tags":["oauth","pkce","gemini","login","state"],"backgroundTag":null,"analyzedSha":"973504e1770928ed5fb82f43da528f441ad9ddc3","analyzedAt":"2026-08-14T23:45:32.408Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}