{"record":{"id":"e2502ad1d6aa49c7","repo":"python/cpython","slug":"invalid-buffer-size","errorCode":null,"errorMessage":"invalid buffer size","messagePattern":"invalid buffer size","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"Lib/_pyio.py","lineNumber":1064,"sourceCode":"\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\n        Returns exactly size bytes of data unless the underlying raw IO\n        stream reaches EOF or if the call would block in non-blocking\n        mode. If size is negative, read until EOF or until read() would\n        block.","sourceCodeStart":1046,"sourceCodeEnd":1082,"githubUrl":"https://github.com/python/cpython/blob/bc6749cc3b5ae4a5e88a6cc2d5b3bebbe354eae6/Lib/_pyio.py#L1046-L1082","documentation":"Raised by the BufferedReader constructor when buffer_size is zero or negative. The wrapper requires a strictly positive buffer size; the check runs after mixin init but before any buffering state is set up. ValueError('invalid buffer size').","triggerScenarios":"io.BufferedReader(raw, 0), io.BufferedReader(raw, -4096), or a computed size that degenerates to 0 (e.g. int(peak_memory / chunk_count) with a bad chunk count).","commonSituations":"Sizing buffers from configuration where 0 means 'unset' elsewhere; passing a user-tunable that was never validated; unit tests probing boundary values.","solutions":["Omit buffer_size to use the DEFAULT_BUFFER_SIZE, or pass a positive int (e.g. 64 * 1024).","Validate/normalize config at load time: buffer_size = max(1, configured) or fall back to the default when <= 0.","Fix the arithmetic that produces 0/negative sizes."],"exampleFix":"# before\nreader = io.BufferedReader(raw, buffer_size=cfg.bufsize)  # cfg.bufsize == 0\n\n# after\nsize = cfg.bufsize if cfg.bufsize and cfg.bufsize > 0 else io.DEFAULT_BUFFER_SIZE\nreader = io.BufferedReader(raw, buffer_size=size)","handlingStrategy":"validation","validationCode":"buffer_size = cfg.bufsize if isinstance(cfg.bufsize, int) and cfg.bufsize > 0 else io.DEFAULT_BUFFER_SIZE\nreader = io.BufferedReader(raw, buffer_size=buffer_size)","typeGuard":"def valid_buffer_size(v) -> bool:\n    return isinstance(v, int) and v > 0","tryCatchPattern":"try:\n    reader = io.BufferedReader(raw, buffer_size=n)\nexcept ValueError:\n    reader = io.BufferedReader(raw)  # fall back to default size","preventionTips":["Treat non-positive configured sizes as 'use default', not as a literal value.","Floor division-derived sizes with max(1, ...).","Validate buffer knobs once at config load."],"tags":["python","io","buffered-reader","valueerror","configuration","buffer-size"],"backgroundTag":null,"analyzedSha":"bc6749cc3b5ae4a5e88a6cc2d5b3bebbe354eae6","analyzedAt":"2026-08-14T22:01:13.976Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}