{"record":{"id":"c5c3ddaa70d713e2","repo":"apache/beam","slug":"whence-mode-r-is-invalid-filesystemio","errorCode":null,"errorMessage":"Whence mode %r is invalid.","messagePattern":"Whence mode %r is invalid\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"sdks/python/apache_beam/io/filesystemio.py","lineNumber":140,"sourceCode":"    Args:\n      offset: seek offset as number.\n      whence: seek mode. Supported modes are os.SEEK_SET (absolute seek),\n        os.SEEK_CUR (seek relative to the current position), and os.SEEK_END\n        (seek relative to the end, offset should be negative).\n\n    Raises:\n      ``ValueError``: When this stream is closed or if whence is invalid.\n    \"\"\"\n    self._checkClosed()\n\n    if whence == os.SEEK_SET:\n      self._position = offset\n    elif whence == os.SEEK_CUR:\n      self._position += offset\n    elif whence == os.SEEK_END:\n      self._position = self._downloader.size + offset\n    else:\n      raise ValueError('Whence mode %r is invalid.' % whence)\n\n    self._position = min(self._position, self._downloader.size)\n    self._position = max(self._position, 0)\n    return self._position\n\n  def tell(self):\n    \"\"\"Tell the stream's current offset.\n\n    Returns:\n      current offset in reading this stream.\n\n    Raises:\n      ``ValueError``: When this stream is closed.\n    \"\"\"\n    self._checkClosed()\n    return self._position\n\n  def seekable(self):","sourceCodeStart":122,"sourceCodeEnd":158,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/python/apache_beam/io/filesystemio.py#L122-L158","documentation":"FilesystemIO (downloader/reader-backed streams) seek() accepts only os.SEEK_SET, os.SEEK_CUR, and os.SEEK_END; any other whence value hits the else branch and raises ValueError('Whence mode %r is invalid.'). The position is then clamped to [0, size], but the whence itself must be one of the three constants.","triggerScenarios":"Calling seek(offset, whence) on a stream obtained from FileSystems.open()/FileSystems.download() with whence not in {0,1,2} — e.g. seek(0, 'begin'), seek(-10, 5), or a non-integer sentinel.","commonSituations":"Hand-rolling file-like wrappers that pass through a custom whence enum; copy-pasted code from libraries that allow string whence values like 'end'.","solutions":["Pass only os.SEEK_SET, os.SEEK_CUR, or os.SEEK_END as whence.","Use the default (SEEK_SET) by calling seek(offset) without a whence argument.","Validate whence before calling: `assert whence in (os.SEEK_SET, os.SEEK_CUR, os.SEEK_END)`.","Replace arbitrary jumps with explicit re-open of the stream when random access isn't needed."],"exampleFix":"// before\nf.seek(-1, 3)  # ValueError: Whence mode 3 is invalid.\n// after\nimport os\nf.seek(-1, os.SEEK_END)","handlingStrategy":"validation","validationCode":"import os\nassert whence in (os.SEEK_SET, os.SEEK_CUR, os.SEEK_END), f'bad whence: {whence!r}'","typeGuard":"def is_valid_whence(whence) -> bool:\n    import os\n    return isinstance(whence, int) and whence in (os.SEEK_SET, os.SEEK_CUR, os.SEEK_END)","tryCatchPattern":"try:\n    pos = f.seek(offset, whence)\nexcept ValueError as e:\n    if 'Whence mode' in str(e):\n        pos = f.seek(offset)  # default SEEK_SET\n    else:\n        raise","preventionTips":["Use only os.SEEK_SET/CUR/END constants for whence on all file-like wrappers.","Normalize string whence ('set','cur','end') to os constants at your wrapper's boundary.","Test seek() with all three whence values in stream unit tests."],"tags":["python","io","seek","invalid-argument"],"backgroundTag":"invalid-enum-value","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-20T03:17:13.778Z"}