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
- If error is expired_token: restart the device flow and approve the prompt promptly
- Poll at the interval the device response specifies (interval field) to avoid slow_down escalation
- For 5xx: retry with backoff — the flow itself must be restarted if the device_code expired meanwhile
- 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
- Have the user approve the device prompt immediately after starting the flow
- Honor the 'interval' from the device authorization response when polling
- Treat any non-pending error as terminal for this device_code — restart the flow, don't keep polling
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
- Device authorization failed {resp.status}: {resp_json}
- Device authorization error: {resp_json.get('error')} - {resp
- device_code is required for polling
- Device authorization failed {resp.status}: {resp_json}
- Device authorization error: {resp_json.get('error')} - {resp
AI-assisted analysis of xtekky/gpt4free@973504e177 (2026-08-14).
Data as JSON: /api/errors/86441a8cec221b9a.
Report an issue: GitHub.