{"record":{"id":"f988b8f697a051e3","repo":"openai/openai-python","slug":"subclasses-of-http-response-classes-cannot-be-pass","errorCode":null,"errorMessage":"Subclasses of HTTP response classes cannot be passed to `cast_to`","messagePattern":"Subclasses of HTTP response classes cannot be passed to `cast_to`","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"src/openai/_legacy_response.py","lineNumber":286,"sourceCode":"            return cast(R, response.text.lower() == \"true\")\n\n        if inspect.isclass(origin) and issubclass(origin, HttpxBinaryResponseContent):\n            return cast(R, cast_to(response))  # type: ignore\n\n        if origin == LegacyAPIResponse:\n            raise RuntimeError(\"Unexpected state - cast_to is `APIResponse`\")\n\n        response_types = http_response_types()\n        if inspect.isclass(\n            origin  # pyright: ignore[reportUnknownArgumentType]\n        ) and issubclass(origin, response_types):\n            # Because of the invariance of our ResponseT TypeVar, users can subclass httpx.Response\n            # and pass that class to our request functions. We cannot change the variance to be either\n            # covariant or contravariant as that makes our usage of ResponseT illegal. We could construct\n            # the response class ourselves but that is something that should be supported directly in httpx\n            # as it would be easy to incorrectly construct the Response object due to the multitude of arguments.\n            if cast_to not in response_types:\n                raise ValueError(\"Subclasses of HTTP response classes cannot be passed to `cast_to`\")\n            return cast(R, response)\n\n        if (\n            inspect.isclass(\n                origin  # pyright: ignore[reportUnknownArgumentType]\n            )\n            and not issubclass(origin, BaseModel)\n            and issubclass(origin, pydantic.BaseModel)\n        ):\n            raise TypeError(\"Pydantic models must subclass our base model type, e.g. `from openai import BaseModel`\")\n\n        if (\n            cast_to is not object\n            and not origin is list\n            and not origin is dict\n            and not origin is Union\n            and not issubclass(origin, BaseModel)\n        ):","sourceCodeStart":268,"sourceCodeEnd":304,"githubUrl":"https://github.com/openai/openai-python/blob/9917c6e28e66e90e1227b3d223c06a8c5441515a/src/openai/_legacy_response.py#L268-L304","documentation":"The SDK only returns its own exact httpx.Response class when cast_to is an HTTP response type. Because the ResponseT TypeVar is invariant, passing a subclass of httpx.Response to cast_to cannot be safely supported, so it is explicitly rejected.","triggerScenarios":"Calling an API method (or using with_raw_response) with cast_to set to a class that subclasses httpx.Response but is not exactly httpx.Response, e.g. cast_to=MyResponse where MyResponse(httpx.Response).","commonSituations":"Developers wanting extra convenience fields on the raw response and subclassing httpx.Response; migrating code from hand-written httpx calls that used custom response classes.","solutions":["Use cast_to=httpx.Response (the exact class) and access extra data via response.headers or the parsed body","Wrap or post-process the returned httpx.Response in your own container class after the call instead of subclassing"],"exampleFix":"# before\nresp = client.post('/models', cast_to=MyHttpResponse, ...)\n# after\nresp = client.post('/models', cast_to=httpx.Response, ...)\nheaders = resp.headers\n","handlingStrategy":"type-guard","validationCode":"import httpx\nassert cast_to is httpx.Response or not (isinstance(cast_to, type) and issubclass(cast_to, httpx.Response) and cast_to is not httpx.Response)","typeGuard":"def is_safe_cast_to(t: object) -> bool:\n    import httpx\n    return t is httpx.Response or not (isinstance(t, type) and issubclass(t, httpx.Response))","tryCatchPattern":null,"preventionTips":["Never subclass httpx.Response for cast_to; wrap the returned object instead"],"tags":["cast-to","typing","httpx","response"],"backgroundTag":"invalid-type-argument","analyzedSha":"9917c6e28e66e90e1227b3d223c06a8c5441515a","analyzedAt":"2026-08-28T11:46:34.183Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}