{"id":"db33fc534670e66f","repo":"encode/httpx","slug":"error-type-0-status-code-0-reason-phrase-f-db33fc","errorCode":null,"errorMessage":"{error_type} '{0.status_code} {0.reason_phrase}' for url '{0.url}'\nFor more information check: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/{0.status_code}","messagePattern":"(.+?) '(.+?) (.+?)' for url '(.+?)'\nFor more information check: https://developer\\.mozilla\\.org/en-US/docs/Web/HTTP/Status/(.+?)","errorType":"http","errorClass":"HTTPStatusError","httpStatus":null,"severity":"error","filePath":"httpx/_models.py","lineNumber":829,"sourceCode":"                \"Redirect location: '{0.headers[location]}'\\n\"\n                \"For more information check: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/{0.status_code}\"\n            )\n        else:\n            message = (\n                \"{error_type} '{0.status_code} {0.reason_phrase}' for url '{0.url}'\\n\"\n                \"For more information check: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/{0.status_code}\"\n            )\n\n        status_class = self.status_code // 100\n        error_types = {\n            1: \"Informational response\",\n            3: \"Redirect response\",\n            4: \"Client error\",\n            5: \"Server error\",\n        }\n        error_type = error_types.get(status_class, \"Invalid status code\")\n        message = message.format(self, error_type=error_type)\n        raise HTTPStatusError(message, request=request, response=self)\n\n    def json(self, **kwargs: typing.Any) -> typing.Any:\n        return jsonlib.loads(self.content, **kwargs)\n\n    @property\n    def cookies(self) -> Cookies:\n        if not hasattr(self, \"_cookies\"):\n            self._cookies = Cookies()\n            self._cookies.extract_cookies(self)\n        return self._cookies\n\n    @property\n    def links(self) -> dict[str | None, dict[str, str]]:\n        \"\"\"\n        Returns the parsed header links of the response, if any\n        \"\"\"\n        header = self.headers.get(\"link\")\n        if header is None:","sourceCodeStart":811,"sourceCodeEnd":847,"githubUrl":"https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/_models.py#L811-L847","documentation":"The non-redirect message format used by `raise_for_status` for any non-success response without a redirect location (4xx, 5xx, or other). It raises `HTTPStatusError` with status code, reason phrase, URL, and an MDN docs link. The `error_type` prefix is chosen from the status class ('Client error', 'Server error', 'Redirect response', 'Informational response').","triggerScenarios":"Calling `response.raise_for_status()` after the server returned 4xx (e.g. 401, 404, 422) or 5xx (500, 502, 503).","commonSituations":"Forgetting that httpx does NOT raise on 4xx/5xx by default (unlike `requests.raise_for_status()` patterns); missing/expired auth tokens producing 401; upstream outages returning 502/503.","solutions":["Wrap the call: `try: r.raise_for_status() except httpx.HTTPStatusError as e: ...` and branch on `e.response.status_code`.","Add retries with backoff for 5xx (and 429) only — do NOT blind-retry 4xx.","For auth flows, refresh the token on 401 before retrying once.","Log `e.response.text` / `e.response.json()` for diagnostics but avoid leaking it to end users."],"exampleFix":"// before\nr = client.get(url)\nr.raise_for_status()  # raises on 404, unhandled\n\n// after\ntry:\n    r = client.get(url)\n    r.raise_for_status()\nexcept httpx.HTTPStatusError as e:\n    if e.response.status_code == 404:\n        return None\n    raise","handlingStrategy":"try-catch","validationCode":"if not response.is_success:\n    status = response.status_code\n    # branch on 4xx vs 5xx before raise_for_status()","typeGuard":"import httpx\n\ndef is_http_error(resp: httpx.Response) -> bool:\n    return resp.status_code >= 400","tryCatchPattern":"try:\n    response.raise_for_status()\nexcept httpx.HTTPStatusError as e:\n    code = e.response.status_code\n    if code == 404:\n        return None\n    if code == 429:\n        backoff_and_retry()\n    if 500 <= code < 600:\n        retry_with_backoff()\n    raise","preventionTips":["httpx never raises on 4xx/5xx automatically - always call raise_for_status() or check status explicitly.","Branch on status code; do not blind-retry 4xx.","Refresh auth tokens on 401 before a single retry."],"tags":["http-status","raise-for-status","http-status-error","client-error","server-error"],"analyzedSha":"b5addb64f0161ff6bfe94c124ef76f6a1fba5254","analyzedAt":"2026-08-04T19:32:56.768Z","schemaVersion":2}