pytest-dev/pytest · error · ValueError
can only process bytes
Error message
can only process bytes
What it means
Raised by LocalPath.write() when the mode string contains 'b' (binary mode) but the supplied data is not a bytes object. The method enforces a strict contract: binary write requires bytes input, text write accepts str (and coerces other types via str()). Supplying a str to a binary-mode write triggers this ValueError before any file handle is opened.
Source
Thrown at src/_pytest/_py/path.py:918
def write_text(self, data, encoding, ensure=False):
"""Write text data into path using the specified encoding.
If ensure is True create missing parent directories.
"""
if ensure:
self.dirpath().ensure(dir=1)
with self.open("w", encoding=encoding) as f:
f.write(data)
def write(self, data, mode="w", ensure=False):
"""Write data into path. If ensure is True create
missing parent directories.
"""
if ensure:
self.dirpath().ensure(dir=1)
if "b" in mode:
if not isinstance(data, bytes):
raise ValueError("can only process bytes")
else:
if not isinstance(data, str):
if not isinstance(data, bytes):
data = str(data)
else:
data = data.decode(sys.getdefaultencoding())
f = self.open(mode)
try:
f.write(data)
finally:
f.close()
def _ensuredirs(self):
parent = self.dirpath()
if parent == self:
return self
if parent.check(dir=0):
parent._ensuredirs()View on GitHub (pinned to 0d6fbdeffa)
Solutions
- If writing text, use mode='w' (the default) or encode first: path.write('hello'.encode('utf-8'), mode='wb').
- If you have bytes, ensure mode includes 'b'.
- Use pathlib.Path.write_bytes / write_text for clearer intent.
Example fix
// before
p.write('hello', mode='wb')
// after
p.write('hello', mode='w') Defensive patterns
Strategy: type-guard
Validate before calling
def safe_write(path, data, mode='w', ensure=False):
if 'b' in mode:
assert isinstance(data, bytes), 'binary mode requires bytes'
path.write(data, mode=mode, ensure=ensure) Type guard
def is_bytes_for_binary(data, mode: str) -> bool:
return 'b' not in mode or isinstance(data, bytes) Prevention
- Match data type to mode: bytes<->'b', str<->'w'.
- Prefer pathlib.Path.write_text / write_bytes to make intent explicit.
When it happens
Trigger: Calling path.write('hello', mode='wb'); calling path.write(some_object, mode='wb') where the object is not bytes.
Common situations: Pickling/serializing to a path and forgetting to encode; porting code that wrote text in binary mode; mixing up data types when writing generated artifacts or snapshots.
Related errors
- mode {mode!r} must be an integer
- no {name!r} checker available for {self.path!r}
- XXX win32
- can only pass None, Path instances or non-empty strings to L
- {relpath!r}: not a string or path object
AI-assisted analysis of pytest-dev/pytest@0d6fbdeffa (2026-08-11).
Data as JSON: /api/errors/5a9849d10e535735.
Report an issue: GitHub.