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

  1. If writing text, use mode='w' (the default) or encode first: path.write('hello'.encode('utf-8'), mode='wb').
  2. If you have bytes, ensure mode includes 'b'.
  3. 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

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


AI-assisted analysis of pytest-dev/pytest@0d6fbdeffa (2026-08-11). Data as JSON: /api/errors/5a9849d10e535735. Report an issue: GitHub.