{"record":{"id":"58515f4c8d9a95d3","repo":"openai/openai-python","slug":"streamalreadyconsumed","errorCode":null,"errorMessage":"StreamAlreadyConsumed","messagePattern":"StreamAlreadyConsumed","errorType":"exception","errorClass":"StreamAlreadyConsumed","httpStatus":null,"severity":"error","filePath":"src/openai/_response.py","lineNumber":346,"sourceCode":"        parsed = self._parse(to=to)\n        if is_given(self._options.post_parser):\n            parsed = self._options.post_parser(parsed)\n\n        if isinstance(parsed, BaseModel):\n            add_request_id(parsed, self.request_id)\n\n        self._parsed_by_type[cache_key] = parsed\n        return cast(R, parsed)\n\n    def read(self) -> bytes:\n        \"\"\"Read and return the binary response content.\"\"\"\n        try:\n            return self.http_response.read()\n        except stream_consumed_exceptions() as exc:\n            # The default error raised by httpx isn't very\n            # helpful in our case so we re-raise it with\n            # a different error message.\n            raise StreamAlreadyConsumed() from exc\n\n    def text(self) -> str:\n        \"\"\"Read and decode the response content into a string.\"\"\"\n        self.read()\n        return self.http_response.text\n\n    def json(self) -> object:\n        \"\"\"Read and decode the JSON response content.\"\"\"\n        self.read()\n        return self.http_response.json()\n\n    def close(self) -> None:\n        \"\"\"Close the response and release the connection.\n\n        Automatically called if the response body is read to completion.\n        \"\"\"\n        self.http_response.close()\n","sourceCodeStart":328,"sourceCodeEnd":364,"githubUrl":"https://github.com/openai/openai-python/blob/9917c6e28e66e90e1227b3d223c06a8c5441515a/src/openai/_response.py#L328-L364","documentation":"The synchronous response's read() re-raises httpx's 'response already read' error as StreamAlreadyConsumed. A streaming response body can only be consumed once; calling read()/text()/json()/parse() again after the body was already read or iterated raises this.","triggerScenarios":"Calling response.read() (or .text(), .json(), .parse()) twice on the same APIResponse, or calling read() after the stream was already consumed by iteration or by an earlier access.","commonSituations":"Retrying logic that re-reads a response, logging the body and then parsing it, or caching/inspecting a response object after it was already consumed.","solutions":["Store the read result once and reuse it instead of re-reading","If you need both text and parsed output, call read() once then use .text or .parse on the cached content","Re-issue the API request to get a fresh response stream"],"exampleFix":"// before\nbody = resp.text()\n... later ...\nagain = resp.read()  # StreamAlreadyConsumed\n\n// after\nbody = resp.text()\ndata = resp.parse(MyModel)  # uses already-read content, no re-read","handlingStrategy":"try-catch","validationCode":"data = resp.read()  # read exactly once, up front\n# subsequent parsing uses cached content:\nmodel = resp.parse(MyModel)","typeGuard":null,"tryCatchPattern":"from openai import StreamAlreadyConsumed\ntry:\n    body = resp.read()\nexcept StreamAlreadyConsumed:\n    body = cached_body  # fall back to previously read content","preventionTips":["Read the response body once and store the result","Never re-read inside retry loops; re-issue the request instead"],"tags":["streaming","response","httpx","read-once"],"backgroundTag":"stream-already-consumed","analyzedSha":"9917c6e28e66e90e1227b3d223c06a8c5441515a","analyzedAt":"2026-08-28T11:46:34.183Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}