{"record":{"id":"ecf4eb6efbf65066","repo":"xtekky/gpt4free","slug":"refresh-failed","errorCode":"REFRESH_FAILED","errorMessage":"{e}","messagePattern":"\\{e\\}","errorType":"exception","errorClass":"TokenManagerError","httpStatus":null,"severity":"error","filePath":"g4f/Provider/qwen/sharedTokenManager.py","lineNumber":113,"sourceCode":"                self.memory_cache[\"credentials\"]\n                and not force_refresh\n                and self.isTokenValid(self.memory_cache[\"credentials\"])\n            ):\n                return self.memory_cache[\"credentials\"]\n\n            if self.refresh_promise:\n                return await self.refresh_promise\n\n            self.refresh_promise = asyncio.create_task(\n                self.performTokenRefresh(qwen_client, force_refresh)\n            )\n            credentials = await self.refresh_promise\n            self.refresh_promise = None\n            return credentials\n        except Exception as e:\n            if isinstance(e, TokenManagerError):\n                raise\n            raise TokenManagerError(TokenError.REFRESH_FAILED, str(e), e) from e\n\n    def checkAndReloadIfNeeded(self):\n        now = int(time.time() * 1000)\n        if now - self.memory_cache[\"last_check\"] < CACHE_CHECK_INTERVAL_MS:\n            return\n        self.memory_cache[\"last_check\"] = now\n\n        try:\n            file_path = self.getCredentialFilePath()\n            stat = file_path.stat()\n            file_mod_time = int(stat.st_mtime * 1000)\n            if file_mod_time > self.memory_cache[\"file_mod_time\"]:\n                self.reloadCredentialsFromFile()\n                self.memory_cache[\"file_mod_time\"] = file_mod_time\n        except FileNotFoundError:\n            self.memory_cache[\"file_mod_time\"] = 0\n        except Exception as e:\n            self.memory_cache[\"credentials\"] = None","sourceCodeStart":95,"sourceCodeEnd":131,"githubUrl":"https://github.com/xtekky/gpt4free/blob/973504e1770928ed5fb82f43da528f441ad9ddc3/g4f/Provider/qwen/sharedTokenManager.py#L95-L131","documentation":"TokenManagerError with code REFRESH_FAILED raised by SharedTokenManager.getValidCredentials (sharedTokenManager.py:113). It is a wrapper: any unexpected exception escaping performTokenRefresh that is not already a TokenManagerError is converted into REFRESH_FAILED with the original message preserved and the cause chained. The inner str(e) identifies the real failure (network error, lock issue, malformed response, etc.).","triggerScenarios":"Awaiting getValidCredentials() while performTokenRefresh raises anything unexpected — aiohttp ClientError, KeyError on response fields, lock-file IO errors — outside the paths that already raise typed TokenManagerError.","commonSituations":"Network drop during the refresh POST; response JSON missing expected keys; credentials file unreadable mid-refresh; asyncio task cancelled; bugs in custom IQwenOAuth2Client implementations.","solutions":["Read the wrapped message and __cause__: fix the underlying failure, not this wrapper","For transient network errors, retry getValidCredentials after a short delay","If the cause is 'Refresh token expired or invalid', re-run device authorization","Upgrade g4f if the inner error suggests response-schema drift"],"exampleFix":"// before\ncreds = await manager.getValidCredentials(qwen_client)\n\n// after\ntry:\n    creds = await manager.getValidCredentials(qwen_client)\nexcept TokenManagerError as e:\n    logger.error(\"refresh failed: %s (cause: %s)\", e.message, e.__cause__)\n    raise","handlingStrategy":"retry","validationCode":null,"typeGuard":"from g4f.Provider.qwen.sharedTokenManager import TokenManagerError\n\ndef is_refresh_failure(exc: Exception) -> bool:\n    return isinstance(exc, TokenManagerError) and exc.error is not None and \"REFRESH\" in str(exc.error)","tryCatchPattern":"try:\n    creds = await manager.getValidCredentials(qwen_client)\nexcept TokenManagerError as e:\n    logger.error(\"refresh failed: %s | cause: %r\", e.message, e.__cause__)\n    if is_transient(e.__cause__):  # e.g. aiohttp.ClientConnectorError\n        await asyncio.sleep(5)\n        creds = await manager.getValidCredentials(qwen_client)\n    else:\n        raise","preventionTips":["Always inspect __cause__ — the wrapper hides the real failure in its message","Retry only transient causes (network); re-auth on expiry causes","Keep the credentials file healthy to reduce unexpected reload failures"],"tags":["qwen","token-manager","refresh","error-wrapping"],"backgroundTag":null,"analyzedSha":"973504e1770928ed5fb82f43da528f441ad9ddc3","analyzedAt":"2026-08-14T23:45:32.408Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}