python/cpython · error · ValueError
peek on closed file
Error message
peek on closed file
What it means
Raised by BytesIO.peek() in Python's pure-Python io module when the stream has already been closed. peek() tries to look ahead into the in-memory buffer without consuming it, but a closed BytesIO has been released and no I/O is permitted. It is a ValueError raised eagerly before any buffer slicing occurs.
Source
Thrown at Lib/_pyio.py:1005
self._pos = pos
elif whence == 1:
with self._lock:
self._pos = max(0, self._pos + pos)
elif whence == 2:
with self._lock:
self._pos = max(0, len(self._buffer) + pos)
else:
raise ValueError("unsupported whence value")
return self._pos
def tell(self):
if self.closed:
raise ValueError("tell on closed file")
return self._pos
def peek(self, size=0):
if self.closed:
raise ValueError("peek on closed file")
if size < 1:
return self._buffer[self._pos:self._pos + io.DEFAULT_BUFFER_SIZE]
return self._buffer[self._pos:self._pos + size]
def truncate(self, pos=None):
if self.closed:
raise ValueError("truncate on closed file")
with self._lock:
if pos is None:
pos = self._pos
else:
try:
pos_index = pos.__index__
except AttributeError:
raise TypeError(f"{pos!r} is not an integer")
else:
pos = pos_index()View on GitHub (pinned to bc6749cc3b)
Solutions
- Ensure peek() is called before close() / before the 'with' block exits.
- Guard the call with 'if not bio.closed:' before peeking.
- If late inspection is intended, keep the raw bytes separately (e.g. getvalue() before closing) instead of peeking a closed stream.
Example fix
// before buf = io.BytesIO(b"data") buf.close() buf.peek(2) # ValueError // after buf = io.BytesIO(b"data") head = buf.peek(2) buf.close()
Defensive patterns
Strategy: validation
Validate before calling
if not buf.closed:
head = buf.peek(4)
else:
head = b"" # stream finished Try / catch
try:
head = buf.peek(4)
except ValueError as e:
if "closed" in str(e):
raise RuntimeError("stream closed before peek") from e
raise Prevention
- Extract data with getvalue() before closing when later inspection is needed.
- Keep all reads/peeks inside the with-block that owns the BytesIO.
- Centralize close() in one owner so consumers never race it.
When it happens
Trigger: Calling bio.peek() (optionally with a size) on a BytesIO instance after bio.close() was called, e.g. peeking during cleanup code or after a with block exited.
Common situations: Peeking inside a 'with io.BytesIO(...) as f:' block after the block exited; reusing a BytesIO stored on an object whose close() lifecycle already ran; test teardown code that closes fixtures then inspects them.
Related errors
- truncate on closed file
- negative truncate position %r
- __getstate__ on closed file
- getvalue on closed file
- getbuffer on closed file
AI-assisted analysis of python/cpython@bc6749cc3b (2026-08-14).
Data as JSON: /api/errors/78c732d704af8b58.
Report an issue: GitHub.