{"record":{"id":"b045b90684f720a9","repo":"xtekky/gpt4free","slug":"response-response-status-html-content-if-is","errorCode":null,"errorMessage":"Response {response.status}: {'HTML content' if is_html else message}","messagePattern":"Response (.+?): (.+?)","errorType":"exception","errorClass":"ResponseStatusError","httpStatus":null,"severity":"error","filePath":"g4f/requests/raise_for_status.py","lineNumber":83,"sourceCode":"    if message is None or is_html:\n        if response.status == 520:\n            message = \"Unknown error (Cloudflare)\"\n    if response.status in (429, 402):\n        raise RateLimitError(f\"Response {response.status}: {message}\")\n    if response.status == 401:\n        raise MissingAuthError(f\"Response {response.status}: {message}\")\n    if response.status == 403 and is_cloudflare(message):\n        raise CloudflareError(f\"Response {response.status}: Cloudflare detected\")\n    elif response.status == 403 and (is_openai(message) or is_lmarena(message)):\n        raise MissingAuthError(f\"Response {response.status}: OpenAI Bot detected\")\n    elif response.status == 502:\n        raise ResponseStatusError(f\"Response {response.status}: Bad Gateway\")\n    elif response.status == 504:\n        raise RateLimitError(f\"Response {response.status}: Gateway Timeout \")\n    elif response.status == 400 and \"API key not valid\" in message:\n        raise MissingAuthError(f\"Response {response.status}: Invalid API key\")\n    else:\n        raise ResponseStatusError(\n            f\"Response {response.status}: {'HTML content' if is_html else message}\"\n        )\n\n\ndef raise_for_status(\n    response: Union[Response, StreamResponse, ClientResponse, RequestsResponse],\n    message: str = None,\n):\n    if hasattr(response, \"status\"):\n        return raise_for_status_async(response, message)\n    if response.ok:\n        return\n    is_html = False\n    if message is None:\n        is_html = response.headers.get(\"content-type\", \"\").startswith(\n            \"text/html\"\n        ) or response.text.startswith(\"<!DOCTYPE\")\n        message = response.text","sourceCodeStart":65,"sourceCodeEnd":101,"githubUrl":"https://github.com/xtekky/gpt4free/blob/973504e1770928ed5fb82f43da528f441ad9ddc3/g4f/requests/raise_for_status.py#L65-L101","documentation":"The fallback branch of g4f's async raise_for_status: any non-ok status that is not 429/402/401/403-with-known-fingerprint/502/504/400-bad-key becomes ResponseStatusError. When the body is HTML the message is the literal 'HTML content' instead of the page, so huge challenge/error pages don't leak into exceptions.","triggerScenarios":"Statuses like 400 (other validation errors), 404 (dead provider endpoint), 405, 408, 418, 500, 501, 503, or any HTML error page not matching the Cloudflare/OpenAI fingerprints.","commonSituations":"Provider changed its URL/API shape (404); upstream 500 crash; request payload rejected with 400 (bad model name, malformed messages); unmaintained provider in an old g4f version.","solutions":["Read the numeric status in the message ('Response {status}: ...') to identify the real cause.","For 404/400: update g4f (pip install -U g4f) — provider endpoints and payloads change often.","For 5xx: retry later or switch provider.","For 400: validate the model name and message format against the provider's current API."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":"from g4f.errors import ResponseStatusError, CloudflareError, RateLimitError\ndef is_generic_status(err: BaseException) -> bool:\n    return isinstance(err, ResponseStatusError) and not isinstance(err, (CloudflareError, RateLimitError))","tryCatchPattern":"from g4f.errors import ResponseStatusError\ntry:\n    result = await client.chat.completions.async_create(...)\nexcept ResponseStatusError as e:\n    status = int(str(e).split(':')[0].split()[-1])\n    if status >= 500:\n        result = await retry_later()\n    elif status in (400, 404):\n        raise RuntimeError(f'Provider API mismatch: {e}') from e\n    else:\n        raise","preventionTips":["Parse the embedded status code to route handling","Pin and regularly update g4f to track provider API changes","Retry only 5xx; fix payload on 400; update g4f on 404","Log the full message once — 'HTML content' still hides the actual status"],"tags":["http-status","fallback","provider-error","async"],"backgroundTag":null,"analyzedSha":"973504e1770928ed5fb82f43da528f441ad9ddc3","analyzedAt":"2026-08-14T23:45:32.408Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}