juicedata/juicefs · error · ValueError
binary mode doesn't take an encoding argument
Error message
binary mode doesn't take an encoding argument
What it means
In binary mode, text decoding parameters are meaningless: open() raises ValueError when encoding (and separately errors/newline) is passed together with a mode containing 'b'. This matches CPython's builtin open() behavior for the JuiceFileSystem wrapper.
Source
Thrown at sdk/python/juicefs/juicefs/juicefs.py:225
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:
try:
sz = c_uint64()
fd = self.lib.jfs_open_posix(c_int64(_tid()), c_int64(self.h), _bin(path), byref(sz), c_int32(flag))
if 'w' in mode:
self.lib.jfs_ftruncate(c_int64(_tid()), fd, c_uint64(0))View on GitHub (pinned to c9a67b23e8)
Solutions
- Drop the encoding argument when using a binary mode.
- If decoding is needed, switch to text mode ('r'/'w') and keep encoding.
- Pass encoding=None conditionally based on whether 'b' is in the mode.
Example fix
# before f = jfs.open(path, 'rb', encoding='utf-8') # after f = jfs.open(path, 'rb') # or jfs.open(path, 'r', encoding='utf-8')
Defensive patterns
Strategy: validation
Validate before calling
if 'b' in mode and encoding is not None:
raise ValueError("encoding is not allowed in binary mode") Type guard
def is_valid_open_call(path, mode, encoding=None) -> bool:
return not ('b' in mode and encoding is not None) Try / catch
try:
f = jfs.open(path, mode, encoding=encoding)
except ValueError as e:
if "binary mode doesn't take an encoding" in str(e):
f = jfs.open(path, mode)
else:
raise Prevention
- Only pass encoding when the mode lacks 'b'.
- Conditionally build kwargs: {'encoding': enc} if 'b' not in mode else {}.
- Avoid forwarding generic opener kwargs blindly into binary open() calls.
When it happens
Trigger: jfs.open(path, 'rb', encoding='utf-8') or jfs.open(path, 'wb', errors='ignore') — any binary mode combined with a non-None encoding argument.
Common situations: Passing through kwargs from a generic file-opener that always supplies encoding; refactored code that switched mode from 'r' to 'rb' but left encoding in the call; default encoding values injected by wrappers.
Related errors
- invalid mode: {mode}
- must have exactly one of create/read/write/append mode
- 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/0f6fe85feb20beb5.
Report an issue: GitHub.