python/cpython · error · ValueError
flush on closed file
Error message
flush on closed file
What it means
BufferedRaw.flush (Lib/_pyio.py:810) checks the closed flag before delegating to the raw stream's flush, raising ValueError when the buffered object has already been closed. This guard prevents writing buffered bytes to a raw descriptor that close() already released.
Source
Thrown at Lib/_pyio.py:810
self._checkClosed()
self._checkWritable()
# Flush the stream. We're mixing buffered I/O with lower-level I/O,
# and a flush may be necessary to synch both views of the current
# file state.
self.flush()
if pos is None:
pos = self.tell()
# XXX: Should seek() be used, instead of passing the position
# XXX directly to truncate?
return self.raw.truncate(pos)
### Flush and close ###
def flush(self):
if self.closed:
raise ValueError("flush on closed file")
self.raw.flush()
def close(self):
if self.raw is not None and not self.closed:
try:
# may raise BlockingIOError or BrokenPipeError etc
self.flush()
finally:
self.raw.close()
def detach(self):
if self.raw is None:
raise ValueError("raw stream already detached")
self.flush()
raw = self._raw
self._raw = None
return raw
View on GitHub (pinned to bc6749cc3b)
Solutions
- Only flush on an open stream: `if not f.closed: f.flush()` in cleanup paths.
- Rely on close() itself — close() already calls flush() internally, so drop redundant explicit flushes before close.
- Use `with` blocks so shutdown order is deterministic and flush happens exactly once.
Example fix
# before
f.close()
try:
f.flush() # ValueError: flush on closed file
finally:
pass
# after
f.close() # close() already flushes; or:
if not f.closed:
f.flush() Defensive patterns
Strategy: validation
Validate before calling
def flush_if_open(f):
if not f.closed:
f.flush() Try / catch
try:
f.flush()
except ValueError as e:
if 'closed file' not in str(e):
raise # a real flush error (e.g. BrokenPipeError subclass paths) — re-raise Prevention
- close() already flushes; do not insert an extra flush before it.
- In cleanup/finally code, always guard flush with `if not f.closed`.
- Let `with` blocks own the flush-then-close sequence instead of hand-rolling it.
When it happens
Trigger: Calling f.flush() after f.close(); flushing inside a `with` block's exit path after an exception already closed the stream; an explicit finally clause that flushes and then a later handler flushes again on a closed object; flushing a detached/closed buffer during interpreter shutdown.
Common situations: Cleanup code that calls both close() and flush() in inconsistent order; retry logic that flushes after an earlier attempt closed the file; __del__ or atexit handlers racing with explicit close.
Related errors
- I/O operation on closed file.
- raw stream already detached
- __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/9230334ee32cc98c.
Report an issue: GitHub.