xtekky/gpt4free · error · RuntimeError

Missing PKCE verifier in state parameter

Error message

Missing PKCE verifier in state parameter

What it means

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.

Source

Thrown at g4f/Provider/needs_auth/GeminiCLI.py:1123

            "scope": " ".join(GEMINICLI_SCOPES),
            "code_challenge": challenge,
            "code_challenge_method": "S256",
            "state": state,
            "access_type": "offline",
            "prompt": "consent",
        }

        url = f"https://accounts.google.com/o/oauth2/v2/auth?{urlencode(params)}"
        return url, verifier, state

    @classmethod
    async def exchange_code_for_tokens(cls, code: str, state: str) -> Dict[str, Any]:
        """Exchange authorization code for access and refresh tokens."""
        decoded_state = decode_oauth_state(state)
        verifier = decoded_state.get("verifier", "")

        if not verifier:
            raise RuntimeError("Missing PKCE verifier in state parameter")

        start_time = time.time()

        async with aiohttp.ClientSession() as session:
            token_data = {
                "client_id": AuthManager.OAUTH_CLIENT_ID,
                "client_secret": AuthManager.OAUTH_CLIENT_SECRET,
                "code": code,
                "grant_type": "authorization_code",
                "redirect_uri": GEMINICLI_REDIRECT_URI,
                "code_verifier": verifier,
            }

            async with session.post(
                "https://oauth2.googleapis.com/token",
                data=token_data,
                headers={"Content-Type": "application/x-www-form-urlencoded"},
            ) as resp:

View on GitHub (pinned to 973504e177)

Solutions

  1. Restart the login flow and copy the FULL redirect URL, including the complete state query parameter
  2. If pasting a raw code, make sure it comes from the same login attempt that generated the state
  3. Avoid editing or re-wrapping the redirect URL (terminals can insert newlines into long query strings)
  4. If it persists, use the localhost callback-server mode instead of manual copy-paste
Defensive patterns

Strategy: validation

Validate before calling

from g4f.Provider.needs_auth.GeminiCLI import decode_oauth_state

def state_has_verifier(state: str) -> bool:
    try:
        return bool(decode_oauth_state(state).get("verifier"))
    except Exception:
        return False

assert state_has_verifier(callback_state), "state lacks PKCE verifier; restart login"

Try / catch

try:
    tokens = await GeminiCLI.exchange_code_for_tokens(code, state)
except RuntimeError as e:
    if "Missing PKCE verifier" in str(e):
        url, verifier, state = GeminiCLI.get_auth_url()  # restart flow
        # prompt the user again with the new URL

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of xtekky/gpt4free@973504e177 (2026-08-14). Data as JSON: /api/errors/4ea73ad90f9283f0. Report an issue: GitHub.