python/cpython · error · UnsupportedOperation

File not open for writing

Error message

File not open for writing

What it means

Raised by FileIO._checkWritable as io.UnsupportedOperation('File not open for writing') when write/writelines/truncate is called on a FileIO whose mode never set the _writable flag (i.e. opened with 'r'/'rb' without '+'). The check fires before any syscall, so nothing is written and errno is not involved.

Source

Thrown at Lib/_pyio.py:1690

    @property
    def _blksize(self):
        if self._stat_atopen is None:
            return DEFAULT_BUFFER_SIZE

        blksize = getattr(self._stat_atopen, "st_blksize", 0)
        # WASI sets blsize to 0
        if not blksize:
            return DEFAULT_BUFFER_SIZE
        return blksize

    def _checkReadable(self):
        if not self._readable:
            raise UnsupportedOperation('File not open for reading')

    def _checkWritable(self, msg=None):
        if not self._writable:
            raise UnsupportedOperation('File not open for writing')

    def read(self, size=None):
        """Read at most size bytes, returned as bytes.

        If size is less than 0, read all bytes in the file making
        multiple read calls. See ``FileIO.readall``.

        Attempts to make only one system call, retrying only per
        PEP 475 (EINTR). This means less data may be returned than
        requested.

        In non-blocking mode, returns None if no data is available.
        Return an empty bytes object at EOF.
        """
        self._checkClosed()
        self._checkReadable()
        if size is None or size < 0:
            return self.readall()

View on GitHub (pinned to bc6749cc3b)

Solutions

  1. Open the file with a write-capable mode ('wb', 'ab', 'r+b') for the handle that receives writes
  2. Use separate handles: one 'rb' reader and one 'ab' writer for append-only logs
  3. Fix the mode string in configuration if it is data-driven

Example fix

# before
f = open('log.txt', 'rb')
f.write(b'entry\n')       # UnsupportedOperation: File not open for writing

# after
with open('log.txt', 'ab') as f:
    f.write(b'entry\n')
Defensive patterns

Strategy: validation

Validate before calling

def write_to(f, data):
    if not f.writable():
        raise io.UnsupportedOperation('File not open for writing')
    return f.write(data)

Type guard

def is_writable_handle(f):
    return not f.closed and f.writable()

Try / catch

try:
    f.write(data)
except io.UnsupportedOperation as e:
    if 'writing' in str(e):
        with open(f.name, 'ab') as g:  # reopen for append
            g.write(data)
    else:
        raise

Prevention

When it happens

Trigger: f = open('in.txt','rb', buffering=0); f.write(b'data') — any write-family call on a read-only FileIO or the TextIOWrapper/BufferedReader stacked above it.

Common situations: Caching/append logic accidentally pointed at a handle opened for reading; code that opens everything 'rb' for safety then attempts telemetry writes; mixing up two variables (reader handle used where the writer was intended).

Related errors


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