{"record":{"id":"d11bf5cd9fabc25e","repo":"xtekky/gpt4free","slug":"failed-to-find-quota-information-in-ollama-setting","errorCode":null,"errorMessage":"Failed to find quota information in Ollama settings page.","messagePattern":"Failed to find quota information in Ollama settings page\\.","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"warning","filePath":"g4f/Provider/local/Ollama.py","lineNumber":118,"sourceCode":"                            \"reset_time\": reset_time,\n                        }\n                    match = re.search(\n                        r'<span class=\"text-sm\">Premium requests</span>\\s*<span class=\"text-sm\">(\\d+)/(\\d+) used</span>\\s*</div>',\n                        html,\n                    )\n                    if match:\n                        used = int(match.group(1))\n                        total = int(match.group(2))\n                        pct = (used / total) * 100 if total > 0 else None\n                        quota[\"premium_requests\"] = {\n                            \"used\": used,\n                            \"total\": total,\n                            \"used_percent\": pct,\n                        }\n        except Exception as e:\n            raise RuntimeError(f\"Failed to get quota information from Ollama: {e}\")\n        if not quota:\n            raise RuntimeError(\n                \"Failed to find quota information in Ollama settings page.\"\n            )\n        return quota\n\n    @classmethod\n    def get_models(cls, api_key: str = None, base_url: str = None, **kwargs):\n        if not cls.models:\n            cls.models = []\n            if not api_key or AppConfig.disable_custom_api_key:\n                api_key = AuthManager.load_api_key(cls)\n            models = requests.get(\n                \"https://ollama.com/api/tags\", timeout=kwargs.get(\"timeout\", 15)\n            ).json()[\"models\"]\n            if models:\n                cls.live += 1\n            cls.models = [model[\"name\"] for model in models]\n            if base_url is None:\n                host = os.getenv(\"OLLAMA_HOST\", \"localhost\")","sourceCodeStart":100,"sourceCodeEnd":136,"githubUrl":"https://github.com/xtekky/gpt4free/blob/973504e1770928ed5fb82f43da528f441ad9ddc3/g4f/Provider/local/Ollama.py#L100-L136","documentation":"RuntimeError raised at the end of the Ollama quota scraper: the settings page was fetched and parsed without exceptions, but the quota dict is still empty — none of the expected markers ('Session usage', 'Hourly usage', 'Weekly usage', premium-request counters) matched in the HTML. This is a silent-layout-change detector: the page loaded, but it does not contain the quota sections in the shape the regexes expect (or the page is a login/landing page that dodged the form heuristics of error 91).","triggerScenarios":"ollama.com redesigning the settings page (labels changed, percentages moved from text to CSS width bars, sections renamed) so every regex misses; the served page being an A/B variant, a consent interstitial, or a post-login redirect stub with no quota markup; a logged-out page that lacks form heuristics but also lacks quota data.","commonSituations":"g4f's Ollama scraper aging out after an ollama.com frontend release; region/language variants of the settings page; viewing quota via a different account type (none/pricing page) with no usage section.","solutions":["Fetch https://ollama.com/settings with your session cookie via curl and confirm the quota section labels actually appear in the HTML.","Verify the session cookie is valid — an auth-redirect page contains no quota markup (see error 91).","If markup changed, update the label list and regexes in Ollama.py's quota scraper to the new page structure.","Treat quota info as non-critical where possible: wrap the quota call and degrade gracefully rather than failing the whole request."],"exampleFix":"# before\nquota = await Ollama.get_quota(api_key)  # raises RuntimeError when page layout changed\n\n# after (degrade gracefully — quota is informational)\ntry:\n    quota = await Ollama.get_quota(api_key)\nexcept RuntimeError as e:\n    logger.warning(f\"Quota unavailable: {e}\")\n    quota = None","handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":"try:\n    quota = await Ollama.get_quota(...)\nexcept RuntimeError as e:\n    if 'find quota information' in str(e):\n        quota = None  # page layout drifted; skip quota display rather than crash\n    else:\n        raise","preventionTips":["Never make quota scraping a hard dependency of request handling.","Monitor ollama.com markup changes if you depend on quota numbers.","Distinguish this 'parsed but empty' case from the exception-wrapped case (error 92) in handlers."],"tags":["ollama","quota","scraping","layout-change"],"backgroundTag":null,"analyzedSha":"973504e1770928ed5fb82f43da528f441ad9ddc3","analyzedAt":"2026-08-14T23:45:32.408Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}