{"record":{"id":"86441a8cec221b9a","repo":"xtekky/gpt4free","slug":"token-poll-failed-resp-status-resp-json","errorCode":null,"errorMessage":"Token poll failed {resp.status}: {resp_json}","messagePattern":"Token poll failed (.+?): (.+?)","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"g4f/Provider/qwen/qwenOAuth2.py","lineNumber":152,"sourceCode":"        async with aiohttp.ClientSession(headers={\"user-agent\": \"\"}) as session:\n            async with session.post(\n                QWEN_OAUTH_TOKEN_ENDPOINT,\n                headers={\n                    \"Content-Type\": \"application/x-www-form-urlencoded\",\n                    \"Accept\": \"application/json\",\n                },\n                data=object_to_urlencoded(body_data),\n            ) as resp:\n                resp_json = await resp.json()\n                if resp.status != 200:\n                    # Check for OAuth RFC 8628 responses\n                    if resp.status == 400:\n                        if \"error\" in resp_json:\n                            if resp_json[\"error\"] == \"authorization_pending\":\n                                return {\"status\": \"pending\"}\n                            if resp_json[\"error\"] == \"slow_down\":\n                                return {\"status\": \"pending\", \"slowDown\": True}\n                    raise Exception(f\"Token poll failed {resp.status}: {resp_json}\")\n                return resp_json\n\n    async def refreshAccessToken(self) -> Union[Dict, ErrorDataDict]:\n        if not self.credentials.get(\"refresh_token\"):\n            raise Exception(\"No refresh token\")\n        body_data = {\n            \"grant_type\": \"refresh_token\",\n            \"refresh_token\": self.credentials[\"refresh_token\"],\n            \"client_id\": QWEN_OAUTH_CLIENT_ID,\n        }\n        async with aiohttp.ClientSession(headers={\"user-agent\": \"\"}) as session:\n            async with session.post(\n                QWEN_OAUTH_TOKEN_ENDPOINT,\n                headers={\n                    \"Content-Type\": \"application/x-www-form-urlencoded\",\n                    \"Accept\": \"application/json\",\n                },\n                data=object_to_urlencoded(body_data),","sourceCodeStart":134,"sourceCodeEnd":170,"githubUrl":"https://github.com/xtekky/gpt4free/blob/973504e1770928ed5fb82f43da528f441ad9ddc3/g4f/Provider/qwen/qwenOAuth2.py#L134-L170","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"while True:\n    result = await oauth.pollDeviceToken(options)\n    if isinstance(result, dict) and result.get(\"status\") == \"pending\":\n        await asyncio.sleep(interval)\n        continue\n    try:\n        ...  # non-pending already returned\n    except Exception:\n        break  # expired_token etc: restart device flow","preventionTips":["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"],"tags":["qwen","oauth","device-flow","polling"],"backgroundTag":null,"analyzedSha":"973504e1770928ed5fb82f43da528f441ad9ddc3","analyzedAt":"2026-08-14T23:45:32.408Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}