{"record":{"id":"ef8e9cd96b43ab37","repo":"python/cpython","slug":"getvalue-on-closed-file","errorCode":null,"errorMessage":"getvalue on closed file","messagePattern":"getvalue on closed file","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"Lib/_pyio.py","lineNumber":912,"sourceCode":"            self._pos = 0\n\n    def __getstate__(self):\n        if self.closed:\n            raise ValueError(\"__getstate__ on closed file\")\n        with self._lock:\n            state = self.__dict__.copy()\n        del state['_lock']\n        return state\n\n    def __setstate__(self, state):\n        self.__dict__.update(state)\n        self._lock = Lock()\n\n    def getvalue(self):\n        \"\"\"Return the bytes value (contents) of the buffer\n        \"\"\"\n        if self.closed:\n            raise ValueError(\"getvalue on closed file\")\n        return bytes(self._buffer)\n\n    def getbuffer(self):\n        \"\"\"Return a readable and writable view of the buffer.\n        \"\"\"\n        if self.closed:\n            raise ValueError(\"getbuffer on closed file\")\n        return memoryview(self._buffer)\n\n    def close(self):\n        if self._buffer is not None:\n            self._buffer = bytearray()\n        super().close()\n\n    def read(self, size=-1):\n        if self.closed:\n            raise ValueError(\"read from closed file\")\n        if size is None:","sourceCodeStart":894,"sourceCodeEnd":930,"githubUrl":"https://github.com/python/cpython/blob/bc6749cc3b5ae4a5e88a6cc2d5b3bebbe354eae6/Lib/_pyio.py#L894-L930","documentation":"BytesIO.getvalue (Lib/_pyio.py:912) returns the entire buffer contents as bytes, but only while the stream is open: close() replaces the buffer with an empty bytearray, so getvalue() on a closed BytesIO raises ValueError instead of returning misleading empty data.","triggerScenarios":"Calling buf.getvalue() after buf.close(); calling getvalue() inside a `with io.BytesIO() as buf:` block's caller after the block exited; returning BytesIO from a producer that closed it, then calling getvalue() in the consumer.","commonSituations":"Mixing explicit close() with later reads in image/PDF/zip generation code; test helpers that build BytesIO payloads and close them to 'free memory' before assertion time.","solutions":["Call getvalue() before close(): `data = buf.getvalue()` then `buf.close()`.","Stop closing BytesIO explicitly; it holds no OS resource, so simply let it go out of scope.","Return bytes from producer functions (getvalue() inside the producer) instead of returning the BytesIO object."],"exampleFix":"# before\nwith io.BytesIO() as buf:\n    buf.write(b'data')\ndata = buf.getvalue()  # after with-block -> closed -> ValueError\n\n# after\nbuf = io.BytesIO()\nbuf.write(b'data')\ndata = buf.getvalue()  # read before any close","handlingStrategy":"validation","validationCode":"def value_of(buf: io.BytesIO) -> bytes:\n    if buf.closed:\n        raise ValueError('BytesIO closed; call getvalue() before close')\n    return buf.getvalue()","typeGuard":"def is_open_bytesio(v) -> bool:\n    return isinstance(v, io.BytesIO) and not v.closed","tryCatchPattern":"try:\n    data = buf.getvalue()\nexcept ValueError as e:\n    if 'closed file' in str(e):\n        data = b''  # buffer already released; nothing to recover\n    else:\n        raise","preventionTips":["Call getvalue() before close(); make it the last-but-one line of the scope.","BytesIO has no OS resource — omit close() entirely in most code.","Functions building payloads should return bytes, not the BytesIO they used."],"tags":["io","bytesio","getvalue","lifecycle","valueerror"],"backgroundTag":null,"analyzedSha":"bc6749cc3b5ae4a5e88a6cc2d5b3bebbe354eae6","analyzedAt":"2026-08-14T22:01:13.976Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}