xtekky/gpt4free · error · Exception

Token poll failed {resp.status}: {resp_json}

Error message

Token poll failed {resp.status}: {resp_json}

What it means

Raised by QwenOAuth2.pollDeviceToken (qwenOAuth2.py:152) when the token endpoint returns non-200 and the error is not one of the RFC 8628 pending states ('authorization_pending', 'slow_down') that the code handles gracefully. Typical causes are 'expired_token' (user never approved), 'invalid_grant', or server 5xx.

Source

Thrown at g4f/Provider/qwen/qwenOAuth2.py:152

        async with aiohttp.ClientSession(headers={"user-agent": ""}) as session:
            async with session.post(
                QWEN_OAUTH_TOKEN_ENDPOINT,
                headers={
                    "Content-Type": "application/x-www-form-urlencoded",
                    "Accept": "application/json",
                },
                data=object_to_urlencoded(body_data),
            ) as resp:
                resp_json = await resp.json()
                if resp.status != 200:
                    # Check for OAuth RFC 8628 responses
                    if resp.status == 400:
                        if "error" in resp_json:
                            if resp_json["error"] == "authorization_pending":
                                return {"status": "pending"}
                            if resp_json["error"] == "slow_down":
                                return {"status": "pending", "slowDown": True}
                    raise Exception(f"Token poll failed {resp.status}: {resp_json}")
                return resp_json

    async def refreshAccessToken(self) -> Union[Dict, ErrorDataDict]:
        if not self.credentials.get("refresh_token"):
            raise Exception("No refresh token")
        body_data = {
            "grant_type": "refresh_token",
            "refresh_token": self.credentials["refresh_token"],
            "client_id": QWEN_OAUTH_CLIENT_ID,
        }
        async with aiohttp.ClientSession(headers={"user-agent": ""}) as session:
            async with session.post(
                QWEN_OAUTH_TOKEN_ENDPOINT,
                headers={
                    "Content-Type": "application/x-www-form-urlencoded",
                    "Accept": "application/json",
                },
                data=object_to_urlencoded(body_data),

View on GitHub (pinned to 973504e177)

Solutions

  1. If error is expired_token: restart the device flow and approve the prompt promptly
  2. Poll at the interval the device response specifies (interval field) to avoid slow_down escalation
  3. For 5xx: retry with backoff — the flow itself must be restarted if the device_code expired meanwhile
  4. Upgrade g4f if poll parameters (grant_type, code_verifier) changed upstream
Defensive patterns

Strategy: retry

Try / catch

while True:
    result = await oauth.pollDeviceToken(options)
    if isinstance(result, dict) and result.get("status") == "pending":
        await asyncio.sleep(interval)
        continue
    try:
        ...  # non-pending already returned
    except Exception:
        break  # expired_token etc: restart device flow

Prevention

When it happens

Trigger: Polling QWEN_OAUTH_TOKEN_ENDPOINT after the device code expired (400 expired_token), polling with a wrong code_verifier (invalid_grant), or hitting 5xx; anything outside the two pending branches raises.

Common situations: User starts device login but doesn't visit the verification URL within the expiry window; slow polling cadence lets the device_code lapse; clock skew; auth service outage mid-flow.

Related errors


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