python/cpython · error · OSError
"raw" argument must be writable.
Error message
"raw" argument must be writable.
What it means
Raised by the BufferedWriter constructor when raw.writable() is False. BufferedWriter only wraps write-capable raw streams and enforces this at construction, raising OSError with the quoted-argument message. Mirrors the readable check on BufferedReader.
Source
Thrown at Lib/_pyio.py:1256
with self._read_lock:
if whence == 1:
pos -= len(self._read_buf) - self._read_pos
pos = _BufferedIOMixin.seek(self, pos, whence)
self._reset_read_buf()
return pos
class BufferedWriter(_BufferedIOMixin):
"""A buffer for a writeable sequential RawIO object.
The constructor creates a BufferedWriter for the given writeable raw
stream. If the buffer_size is not given, it defaults to
DEFAULT_BUFFER_SIZE.
"""
def __init__(self, raw, buffer_size=DEFAULT_BUFFER_SIZE):
if not raw.writable():
raise OSError('"raw" argument must be writable.')
_BufferedIOMixin.__init__(self, raw)
if buffer_size <= 0:
raise ValueError("invalid buffer size")
self.buffer_size = buffer_size
self._write_buf = bytearray()
self._write_lock = Lock()
def writable(self):
return self.raw.writable()
def write(self, b):
if isinstance(b, str):
raise TypeError("can't write str to binary stream")
with self._write_lock:
if self.closed:
raise ValueError("write to closed file")
# XXX we can implement some more tricks to try and avoidView on GitHub (pinned to bc6749cc3b)
Solutions
- Wrap a genuinely writable raw stream: files opened 'wb'/'ab', the pipe write end, or a writable socket.
- Implement writable() -> True on custom raw stream classes.
- Probe raw.writable() before constructing to produce a domain-specific error.
Example fix
# before r, w = os.pipe() writer = io.BufferedWriter(os.fdopen(r, 'rb')) # read end -> OSError # after r, w = os.pipe() writer = io.BufferedWriter(os.fdopen(w, 'wb'))
Defensive patterns
Strategy: validation
Validate before calling
if not raw.writable():
raise ValueError("supplied raw stream does not support writing")
writer = io.BufferedWriter(raw) Type guard
def is_writable_raw(obj) -> bool:
return hasattr(obj, "writable") and callable(getattr(obj, "write")) and obj.writable() Try / catch
try:
writer = io.BufferedWriter(raw)
except OSError as e:
raise ValueError(f"need the write end, got: {raw!r}") from e Prevention
- Open destination files with 'wb'/'ab' before wrapping.
- Don't shutdown(SHUT_WR) sockets you intend to write to.
- Implement writable() -> True on custom sinks.
When it happens
Trigger: io.BufferedWriter(os.fdopen(rfd, 'rb')) using a pipe read end; wrapping a file opened 'rb'; custom raw stream whose writable() defaults to False (RawIOBase default) because it was not overridden.
Common situations: Swapped pipe ends; passing a socket half that is shut down for writing (shutdown(SHUT_WR) makes writes invalid); custom sink classes forgetting to implement writable().
Related errors
- "raw" argument must be readable.
- write() returned incorrect number of bytes
- "reader" argument must be readable.
- "writer" argument must be writable.
- {e.strerror}
AI-assisted analysis of python/cpython@bc6749cc3b (2026-08-14).
Data as JSON: /api/errors/261c7b97011012e2.
Report an issue: GitHub.