juicedata/juicefs · error · ValueError

invalid whence ({whence}, should be {os.SEEK_SET}, {os.SEEK_

Error message

invalid whence ({whence}, should be {os.SEEK_SET}, {os.SEEK_CUR} or {os.SEEK_END})

What it means

Raised by JuiceFile.seek in the Python SDK when the whence argument is not one of os.SEEK_SET (0), os.SEEK_CUR (1), or os.SEEK_END (2). The seek offset cannot be interpreted without a valid reference point, so the bad whence is rejected before any jfs call.

Source

Thrown at sdk/python/juicefs/juicefs/juicefs.py:564

            raise io.UnsupportedOperation('not writable')

        if not data:
            return 0
        if self.append:
            self.off = self.length
        n = self.lib.jfs_pwrite(c_int64(_tid()), c_int32(self.fd), data, c_int32(len(data)), c_int64(self.off))
        self.off += n
        if self.off > self.length:
            self.length = self.off
        return n

    def seek(self, offset, whence=0):
        """Set the stream position to the given byte offset.
        offset is interpreted relative to the position indicated by whence.
        The default value for whence is SEEK_SET."""
        self._check_closed()
        if whence not in (os.SEEK_SET, os.SEEK_CUR, os.SEEK_END):
            raise ValueError(f'invalid whence ({whence}, should be {os.SEEK_SET}, {os.SEEK_CUR} or {os.SEEK_END})')
        if whence == os.SEEK_SET:
            self.off = offset
        elif whence == os.SEEK_CUR:
            self.off += offset
        else:
            self.off = self.length + offset
        return self.off

    def tell(self):
        """Return the current stream position."""
        self._check_closed()
        return self.off

    def truncate(self, size=None):
        """Truncate the file to at most size bytes.
        Size defaults to the current file position, as returned by tell()."""
        self._check_closed()
        if not self.writable():

View on GitHub (pinned to c9a67b23e8)

Solutions

  1. Pass one of os.SEEK_SET, os.SEEK_CUR, os.SEEK_END (or 0/1/2)
  2. Default to f.seek(offset) which uses whence=0 (SEEK_SET)
  3. Validate/normalize the whence parameter before calling seek

Example fix

// before
f.seek(100, 'cur')
// after
import os
f.seek(100, os.SEEK_CUR)
Defensive patterns

Strategy: validation

Validate before calling

import os
VALID_WHENCE = (os.SEEK_SET, os.SEEK_CUR, os.SEEK_END)
if whence not in VALID_WHENCE:
    whence = os.SEEK_SET

Type guard

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

Try / catch

try:
    f.seek(off, whence)
except ValueError:
    f.seek(off)

Prevention

When it happens

Trigger: Calling f.seek(offset, 3) or f.seek(offset, 'cur'); passing a string whence copied from another API; computing whence dynamically and producing a bad value.

Common situations: Porting from APIs that accept string whence ('SET'/'CUR'/'END'); off-by-one or None whence from config; wrapping seek in a helper with an unvalidated parameter.

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 juicedata/juicefs@c9a67b23e8 (2026-09-06). Data as JSON: /api/errors/e9de595ceb479bcb. Report an issue: GitHub.