python/cpython · error · ValueError

getvalue on closed file

Error message

getvalue on closed file

What it means

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.

Source

Thrown at Lib/_pyio.py:912

            self._pos = 0

    def __getstate__(self):
        if self.closed:
            raise ValueError("__getstate__ on closed file")
        with self._lock:
            state = self.__dict__.copy()
        del state['_lock']
        return state

    def __setstate__(self, state):
        self.__dict__.update(state)
        self._lock = Lock()

    def getvalue(self):
        """Return the bytes value (contents) of the buffer
        """
        if self.closed:
            raise ValueError("getvalue on closed file")
        return bytes(self._buffer)

    def getbuffer(self):
        """Return a readable and writable view of the buffer.
        """
        if self.closed:
            raise ValueError("getbuffer on closed file")
        return memoryview(self._buffer)

    def close(self):
        if self._buffer is not None:
            self._buffer = bytearray()
        super().close()

    def read(self, size=-1):
        if self.closed:
            raise ValueError("read from closed file")
        if size is None:

View on GitHub (pinned to bc6749cc3b)

Solutions

  1. Call getvalue() before close(): `data = buf.getvalue()` then `buf.close()`.
  2. Stop closing BytesIO explicitly; it holds no OS resource, so simply let it go out of scope.
  3. Return bytes from producer functions (getvalue() inside the producer) instead of returning the BytesIO object.

Example fix

# before
with io.BytesIO() as buf:
    buf.write(b'data')
data = buf.getvalue()  # after with-block -> closed -> ValueError

# after
buf = io.BytesIO()
buf.write(b'data')
data = buf.getvalue()  # read before any close
Defensive patterns

Strategy: validation

Validate before calling

def value_of(buf: io.BytesIO) -> bytes:
    if buf.closed:
        raise ValueError('BytesIO closed; call getvalue() before close')
    return buf.getvalue()

Type guard

def is_open_bytesio(v) -> bool:
    return isinstance(v, io.BytesIO) and not v.closed

Try / catch

try:
    data = buf.getvalue()
except ValueError as e:
    if 'closed file' in str(e):
        data = b''  # buffer already released; nothing to recover
    else:
        raise

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of python/cpython@bc6749cc3b (2026-08-14). Data as JSON: /api/errors/ef8e9cd96b43ab37. Report an issue: GitHub.