{"record":{"id":"bd837c91c736b93f","repo":"python/cpython","slug":"raw-argument-must-be-readable","errorCode":null,"errorMessage":"\"raw\" argument must be readable.","messagePattern":"\"raw\" argument must be readable\\.","errorType":"exception","errorClass":"OSError","httpStatus":null,"severity":"error","filePath":"Lib/_pyio.py","lineNumber":1060,"sourceCode":"        return True\n\n\nclass BufferedReader(_BufferedIOMixin):\n\n    \"\"\"BufferedReader(raw[, buffer_size])\n\n    A buffer for a readable, sequential BaseRawIO object.\n\n    The constructor creates a BufferedReader for the given readable raw\n    stream and buffer_size. If buffer_size is omitted, DEFAULT_BUFFER_SIZE\n    is used.\n    \"\"\"\n\n    def __init__(self, raw, buffer_size=DEFAULT_BUFFER_SIZE):\n        \"\"\"Create a new buffered reader using the given readable raw IO object.\n        \"\"\"\n        if not raw.readable():\n            raise OSError('\"raw\" argument must be readable.')\n\n        _BufferedIOMixin.__init__(self, raw)\n        if buffer_size <= 0:\n            raise ValueError(\"invalid buffer size\")\n        self.buffer_size = buffer_size\n        self._reset_read_buf()\n        self._read_lock = Lock()\n\n    def readable(self):\n        return self.raw.readable()\n\n    def _reset_read_buf(self):\n        self._read_buf = b\"\"\n        self._read_pos = 0\n\n    def read(self, size=None):\n        \"\"\"Read size bytes.\n","sourceCodeStart":1042,"sourceCodeEnd":1078,"githubUrl":"https://github.com/python/cpython/blob/bc6749cc3b5ae4a5e88a6cc2d5b3bebbe354eae6/Lib/_pyio.py#L1042-L1078","documentation":"Raised by the BufferedReader constructor when the supplied raw stream is not readable (raw.readable() returns False). BufferedReader is strictly a read-side wrapper, so it validates the raw object's capability at construction time and raises OSError (not ValueError) with the quoted-argument message.","triggerScenarios":"io.BufferedReader(raw) where raw is write-only, e.g. another BufferedWriter, an os.pipe write end wrapped with os.fdopen(wfd, 'wb'), or a custom RawIO whose readable() returns False.","commonSituations":"Mixing up the read and write ends of a pipe; wrapping a socket/file opened for writing only; passing the wrong half of a socketpair; custom raw streams that forgot to override readable() (RawIOBase default returns False).","solutions":["Pass a readable raw stream: open the file in 'rb', use the pipe read end, or the correct socket half.","For custom raw classes, override readable() to return True when reads are supported.","Check raw.readable() yourself before wrapping to give a clearer upstream error."],"exampleFix":"# before\nr, w = os.pipe()\nreader = io.BufferedReader(os.fdopen(w, 'wb'))  # write end -> OSError\n\n# after\nr, w = os.pipe()\nreader = io.BufferedReader(os.fdopen(r, 'rb'))","handlingStrategy":"validation","validationCode":"if not raw.readable():\n    raise ValueError(\"supplied raw stream does not support reading\")\nreader = io.BufferedReader(raw)","typeGuard":"def is_readable_raw(obj) -> bool:\n    return hasattr(obj, \"readable\") and callable(getattr(obj, \"read\")) and obj.readable()","tryCatchPattern":"try:\n    reader = io.BufferedReader(raw)\nexcept OSError as e:\n    raise ValueError(f\"need the read end, got: {raw!r}\") from e","preventionTips":["Name pipe/socket ends clearly (read_end/write_end) at creation.","For custom raw streams, override readable() to return True.","Prefer os.fdopen with an explicit 'rb' mode."],"tags":["python","io","buffered-reader","oserror","constructor","pipe"],"backgroundTag":null,"analyzedSha":"bc6749cc3b5ae4a5e88a6cc2d5b3bebbe354eae6","analyzedAt":"2026-08-14T22:01:13.976Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}