juicedata/juicefs · error · ValueError
must have exactly one of create/read/write/append mode
Error message
must have exactly one of create/read/write/append mode
What it means
After scanning the mode characters, open() requires exactly one base mode: r, w, x or a. cnt != 1 (zero base modes like '+' or 'tb' alone, or multiple like 'rwa') raises this ValueError. Mirrors CPython's builtin open() error message.
Source
Thrown at sdk/python/juicefs/juicefs/juicefs.py:220
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")
if encoding:
raise ValueError("binary mode doesn't take an encoding argument")
if errors:
raise ValueError("binary mode doesn't take an errors argument")
else:
if not encoding:
encoding = locale.getpreferredencoding(False).lower()
if not errors:
errors = 'strict'
codecs.lookup(encoding)
size = 0
if 'x' in mode:
fd = self.lib.jfs_create(c_int64(_tid()), c_int64(self.h), _bin(path), c_uint16(0o666), c_uint16(self.umask))
else:View on GitHub (pinned to c9a67b23e8)
Solutions
- Set exactly one of 'r', 'w', 'x' or 'a' in the mode string.
- For read+write use 'r+' or 'w+' rather than 'rw'.
- Validate config-supplied modes against ^(r|w|x|a)[+]?[tb]?$ before calling open.
Example fix
# before f = jfs.open(path, 'rw') # two base modes # after f = jfs.open(path, 'r+') # exactly one base mode
Defensive patterns
Strategy: validation
Validate before calling
import re
if not re.fullmatch(r'(r|w|x|a)\+?[tb]?', mode):
raise ValueError(f'mode must have exactly one of r/w/x/a: {mode}') Type guard
def has_exactly_one_base_mode(mode) -> bool:
return isinstance(mode, str) and sum(c in 'rwxa' for c in mode) == 1 Try / catch
try:
f = jfs.open(path, mode)
except ValueError as e:
if 'exactly one of create/read/write/append' in str(e):
f = jfs.open(path, mode + 'r' if sum(c in 'rwxa' for c in mode) == 0 else 'r+')
else:
raise Prevention
- Use 'r+'/'w+' instead of 'rw' for combined read-write.
- Never pass '' or modifier-only modes like '+' or 'b'.
- Validate config/default modes against a strict regex at startup.
When it happens
Trigger: open(path, '+'), open(path, 'b'), open(path, 't'), open(path, 'rwa'), open(path, '') — zero or 2+ base-mode characters.
Common situations: Constructing the mode dynamically and ending up with only '+' or 'b'; concatenating 'a' onto 'rw' making 'rwa'; empty mode string from a config value defaulting to ''.
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
- invalid mode: {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/ff4a03187bd6f02c.
Report an issue: GitHub.