juicedata/juicefs · error · ValueError
invalid mode: {mode}
Error message
invalid mode: {mode} What it means
JuiceFileSystem.open() validates the mode string like builtin open(): it rejects modes containing duplicate characters (len(mode) != len(set(mode))) and unknown characters. This specific raise covers both duplicate characters and any character not in 'rwxa+tb' encountered in the parse loop. It's a fail-fast ValueError before any file operation.
Source
Thrown at sdk/python/juicefs/juicefs/juicefs.py:205
def stat(self, path):
"""Get the status of a file or a directory."""
fi = FileInfo()
self.lib.jfs_stat(c_int64(_tid()), c_int64(self.h), _bin(path), byref(fi))
return os.stat_result((fi.mode, fi.inode, 0, fi.nlink, fi.uid, fi.gid, fi.length, fi.atime, fi.mtime, fi.ctime))
def exists(self, path):
"""Check if a file exists."""
try:
self.stat(path)
return True
except OSError as e:
return False
def open(self, path, mode='r', buffering=-1, encoding=None, errors=None):
"""Open a file, returns a filelike object."""
if len(mode) != len(set(mode)):
raise ValueError(f'invalid mode: {mode}')
flag = 0
cnt = 0
for c in mode:
if c in 'rwxa':
cnt += 1
if c == 'r':
flag |= MODE_READ
else:
flag |= MODE_WRITE
elif c == '+':
flag |= MODE_READ | MODE_WRITE
elif c not in 'tb':
raise ValueError(f'invalid mode: {mode}')
if cnt != 1:
raise ValueError('must have exactly one of create/read/write/append mode')
if 'b' in mode:
if 't' in mode:
raise ValueError("can't have text and binary mode at once")View on GitHub (pinned to c9a67b23e8)
Solutions
- Use a mode with unique characters drawn only from 'rwxa', plus optional '+' and 'tb'.
- Include exactly one of r/w/x/a — see also the cnt != 1 check.
- Match Python's builtin open() mode grammar: e.g. 'r', 'rb', 'w', 'w+', 'a'.
Example fix
# before f = jfs.open(path, 'rw') # duplicates? 'rw' ok, but 'rr' or 'rww' fails # after f = jfs.open(path, 'r+') # read+write with a single 'r'/'w' base
Defensive patterns
Strategy: validation
Validate before calling
def validate_mode(mode):
if len(mode) != len(set(mode)) or any(c not in 'rwxa+tb' for c in mode):
raise ValueError(f'invalid mode: {mode}')
return mode Type guard
def is_valid_mode(mode) -> bool:
return isinstance(mode, str) and len(mode) == len(set(mode)) and all(c in 'rwxa+tb' for c in mode) Try / catch
try:
f = jfs.open(path, mode)
except ValueError as e:
if 'invalid mode' in str(e):
mode = sanitize_mode(mode)
f = jfs.open(path, mode)
else:
raise Prevention
- Reuse the same mode strings as builtin open(): r, rb, w, wb, a, r+, w+.
- Never build mode strings by concatenation without deduplication.
- Sanitize user/config-supplied modes before passing them to open().
When it happens
Trigger: open(path, 'rr'), open(path, 'w+w'), or open(path, 'q') — any mode with a repeated character or a character outside rwxa+tb.
Common situations: Programmatically building a mode string and duplicating flags; typos ('re' containing 'e'); porting code that uses C-style modes like 'rb+' is fine, but 'z' or 'O_RDWR' constants leaked into the string are not.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- must have exactly one of create/read/write/append mode
- binary mode doesn't take an encoding argument
- can't have text and binary mode at once
- binary mode doesn't take an errors argument
- Invalid start or len parameter
AI-assisted analysis of juicedata/juicefs@c9a67b23e8 (2026-09-06).
Data as JSON: /api/errors/a6b830c01c2ec157.
Report an issue: GitHub.