apache/beam · error · ValueError

Whence mode %r is invalid.

Error message

Whence mode %r is invalid.

What it means

CompressedFile.seek() only supports the three standard whence modes: os.SEEK_SET, os.SEEK_CUR, and os.SEEK_END. Any other whence value falls through all branches and raises ValueError("Whence mode %r is invalid."). Compressed streams additionally impose ordering constraints on SEEK_END, but the whence value itself must always be one of the three constants.

Solutions

  1. Use the standard constants os.SEEK_SET, os.SEEK_CUR, or os.SEEK_END as the whence argument.
  2. Drop the whence argument entirely for the common case: seek(n) defaults to SEEK_SET.
  3. Guard the whence value before calling seek: assert whence in (os.SEEK_SET, os.SEEK_CUR, os.SEEK_END).

Example fix

// before
f.seek(0, 'end')  # ValueError: Whence mode 'end' is invalid.
// after
import os
f.seek(0, os.SEEK_END)
Defensive patterns

Strategy: validation

Validate before calling

import os
assert whence in (os.SEEK_SET, os.SEEK_CUR, os.SEEK_END), f'bad whence: {whence!r}'

Type guard

def is_valid_whence(whence) -> bool:
    import os
    return whence in (os.SEEK_SET, os.SEEK_CUR, os.SEEK_END)

Try / catch

try:
    f.seek(offset, whence)
except ValueError as e:
    if 'Whence mode' in str(e):
        f.seek(offset)  # fall back to SEEK_SET
    else:
        raise

Prevention

When it happens

Trigger: Calling `compressed_file.seek(offset, whence)` with whence not in {0,1,2} — e.g. a string like seek(0, 'start'), a custom sentinel like seek(0, 10), or a typo'd constant.

Common situations: Porting code that used nonstandard whence enums from another library; passing a string whence because the caller confused file-like seek with a custom API; dynamically computing whence and producing a wrong type.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


AI-assisted analysis of apache/beam@12126d8942 (2026-09-13). Data as JSON: /api/errors/4372fc752c760cdb. Report an issue: GitHub.

Appendix: source

Thrown at sdks/python/apache_beam/io/filesystem.py:416

    elif whence == os.SEEK_END:
      # Determine and cache the uncompressed size of the file
      if not self._uncompressed_size:
        logger.warning(
            "Seeking relative from end of file is requested. "
            "Need to decompress the whole file once to determine "
            "its size. This might take a while...")
        uncompress_start_time = time.time()
        while self.read(self._read_size):
          pass
        uncompress_end_time = time.time()
        logger.warning(
            "Full file decompression for seek "
            "from end took %.2f secs",
            (uncompress_end_time - uncompress_start_time))
        self._uncompressed_size = self._uncompressed_position
      absolute_offset = self._uncompressed_size + offset
    else:
      raise ValueError("Whence mode %r is invalid." % whence)

    # Determine how many bytes needs to be read before we reach
    # the requested offset. Rewind if we already passed the position.
    if absolute_offset < self._uncompressed_position:
      self._rewind()
    bytes_to_skip = absolute_offset - self._uncompressed_position

    # Read until the desired position is reached or EOF occurs.
    while bytes_to_skip:
      data = self.read(min(self._read_size, bytes_to_skip))
      if not data:
        break
      bytes_to_skip -= len(data)

  def tell(self) -> int:
    """Returns current position in uncompressed file."""
    return self._uncompressed_position

View on GitHub (pinned to 12126d8942)