{"record":{"id":"07ae6081b6a855bd","repo":"xtekky/gpt4free","slug":"authorization-was-denied-by-the-user","errorCode":null,"errorMessage":"Authorization was denied by the user.","messagePattern":"Authorization was denied by the user\\.","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"g4f/Provider/github/githubOAuth2.py","lineNumber":152,"sourceCode":"                GITHUB_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\n                # Check for OAuth RFC 8628 responses\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                    if resp_json[\"error\"] == \"expired_token\":\n                        raise Exception(\"Device code expired. Please try again.\")\n                    if resp_json[\"error\"] == \"access_denied\":\n                        raise Exception(\"Authorization was denied by the user.\")\n                    raise Exception(\n                        f\"Token poll failed: {resp_json.get('error')} - {resp_json.get('error_description')}\"\n                    )\n\n                return resp_json\n\n    def isTokenValid(self, credentials: GithubCredentials) -> bool:\n        \"\"\"GitHub tokens don't expire by default, but we track expiry_date if set\"\"\"\n        if not credentials.get(\"access_token\"):\n            return False\n        expiry_date = credentials.get(\"expiry_date\")\n        if expiry_date is None:\n            # GitHub tokens don't expire unless explicitly set\n            return True\n        return time.time() * 1000 < expiry_date - TOKEN_REFRESH_BUFFER_MS\n","sourceCodeStart":134,"sourceCodeEnd":168,"githubUrl":"https://github.com/xtekky/gpt4free/blob/973504e1770928ed5fb82f43da528f441ad9ddc3/g4f/Provider/github/githubOAuth2.py#L134-L168","documentation":"A bare Exception raised inside pollDeviceToken when the token endpoint returns the RFC 8628 error 'access_denied'. Unlike pending/expired states, this is a terminal, deliberate outcome: the user (or an org policy on their behalf) rejected the authorization request at the verification page, so no token will ever be issued for this device_code.","triggerScenarios":"During device login the user clicked 'Deny'/cancel on github.com/login/device, or an organization's OAuth policy auto-denied the g4f application.","commonSituations":"User mistyped/abandoned the flow and denied it to dismiss the page; enterprise-managed GitHub accounts with restricted third-party OAuth app allowlists blocking g4f's client_id.","solutions":["Restart the flow and approve the requested scopes on the verification page","If an org manages the account, request the g4f OAuth app be allowlisted or use a personal account","Treat access_denied as non-retryable for this code — do not loop polling after catching it"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try:\n    result = await client.pollDeviceToken({'device_code': code})\nexcept Exception as e:\n    if 'denied' in str(e).lower():\n        abort_login()  # terminal: user or org policy refused — do not retry this code\n    raise","preventionTips":["Treat access_denied as terminal for the current device_code; only a fresh flow can succeed","For enterprise GitHub accounts, confirm the OAuth app is allowlisted before offering login","Show a clear 'authorization denied' message instead of retrying silently"],"tags":["oauth","device-flow","access-denied","github"],"backgroundTag":null,"analyzedSha":"973504e1770928ed5fb82f43da528f441ad9ddc3","analyzedAt":"2026-08-14T23:45:32.408Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}