{"record":{"id":"c4656c7050609b5c","repo":"python/cpython","slug":"invalid-whence-value","errorCode":null,"errorMessage":"invalid whence value","messagePattern":"invalid whence value","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"Lib/_pyio.py","lineNumber":1236,"sourceCode":"                # Otherwise refill internal buffer - unless we're\n                # in read1 mode and already got some data\n                elif not (read1 and written):\n                    if not self._peek_unlocked(1):\n                        break # eof\n\n                # In readinto1 mode, return as soon as we have some data\n                if read1 and written:\n                    break\n\n        return written\n\n    def tell(self):\n        # GH-95782: Keep return value non-negative\n        return max(_BufferedIOMixin.tell(self) - len(self._read_buf) + self._read_pos, 0)\n\n    def seek(self, pos, whence=0):\n        if whence not in valid_seek_flags:\n            raise ValueError(\"invalid whence value\")\n        self._checkClosed(\"seek of closed file\")\n        with self._read_lock:\n            if whence == 1:\n                pos -= len(self._read_buf) - self._read_pos\n            pos = _BufferedIOMixin.seek(self, pos, whence)\n            self._reset_read_buf()\n            return pos\n\nclass BufferedWriter(_BufferedIOMixin):\n\n    \"\"\"A buffer for a writeable sequential RawIO object.\n\n    The constructor creates a BufferedWriter for the given writeable raw\n    stream. If the buffer_size is not given, it defaults to\n    DEFAULT_BUFFER_SIZE.\n    \"\"\"\n\n    def __init__(self, raw, buffer_size=DEFAULT_BUFFER_SIZE):","sourceCodeStart":1218,"sourceCodeEnd":1254,"githubUrl":"https://github.com/python/cpython/blob/bc6749cc3b5ae4a5e88a6cc2d5b3bebbe354eae6/Lib/_pyio.py#L1218-L1254","documentation":"Raised by BufferedReader.seek(pos, whence) when whence is not in valid_seek_flags (0/SEEK_SET, 1/SEEK_CUR, 2/SEEK_END in the stdlib set). The check runs before the closed-file check, so even a closed reader complains about whence first. ValueError('invalid whence value').","triggerScenarios":"reader.seek(0, 3), reader.seek(0, -1), or forwarding a whence obtained from another API whose enum differs; also passing the arguments swapped: seek(0, pos) makes the position land in the whence slot.","commonSituations":"Argument-order mistakes (seek(offset, whence) vs seek(whence, offset)); using non-constant sentinel values (e.g. os.SEEK_ constants vs homemade 3=SEEK_DATA on a reader that does not accept it); forwarding user input without validation.","solutions":["Pass whence as one of os.SEEK_SET / os.SEEK_CUR / os.SEEK_END (0, 1, 2).","Verify argument order: seek(offset, whence).","Map/validate external whence codes to the standard constants before calling seek."],"exampleFix":"# before\nreader.seek(os.SEEK_SET, 10)  # args swapped -> whence=0 pos... actually invalid\n\n# after\nreader.seek(10, os.SEEK_SET)","handlingStrategy":"validation","validationCode":"import os\nassert whence in (os.SEEK_SET, os.SEEK_CUR, os.SEEK_END)\nreader.seek(pos, whence)","typeGuard":"def valid_whence(w) -> bool:\n    import os\n    return w in (os.SEEK_SET, os.SEEK_CUR, os.SEEK_END)","tryCatchPattern":"try:\n    reader.seek(pos, whence)\nexcept ValueError as e:\n    if \"whence\" in str(e):\n        reader.seek(pos, os.SEEK_SET)  # or raise with caller context\n    else:\n        raise","preventionTips":["Always use os.SEEK_* constants, never raw ints or other enums.","Remember the signature is seek(offset, whence).","Validate forwarded whence codes at API boundaries."],"tags":["python","io","buffered-reader","seek","valueerror","argument-order"],"backgroundTag":null,"analyzedSha":"bc6749cc3b5ae4a5e88a6cc2d5b3bebbe354eae6","analyzedAt":"2026-08-14T22:01:13.976Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}