python/cpython · error · TypeError

data argument must be a bytes-like object, not {type(data)._

Error message

data argument must be a bytes-like object, not {type(data).__name__}

What it means

On the Windows proactor event loop, write transports accept only bytes-like data (bytes, bytearray, memoryview) because the data is handed straight to the OS overlapped WriteFile. Passing str (the most common mistake) or arbitrary objects raises this TypeError before any I/O starts.

Source

Thrown at Lib/asyncio/proactor_events.py:337

            if not self._closing:
                raise
        else:
            if not self._paused:
                self._read_fut.add_done_callback(self._loop_reading)
        finally:
            if length > -1:
                self._data_received(data, length)


class _ProactorBaseWritePipeTransport(_ProactorBasePipeTransport,
                                      transports.WriteTransport):
    """Transport for write pipes."""

    _start_tls_compatible = True

    def write(self, data):
        if not isinstance(data, (bytes, bytearray, memoryview)):
            raise TypeError(
                f"data argument must be a bytes-like object, "
                f"not {type(data).__name__}")
        if self._eof_written:
            raise RuntimeError('write_eof() already called')
        if self._empty_waiter is not None:
            raise RuntimeError('unable to write; sendfile is in progress')

        if not data:
            return

        if self._conn_lost:
            if self._conn_lost >= constants.LOG_THRESHOLD_FOR_CONNLOST_WRITES:
                logger.warning('socket.send() raised exception.')
            self._conn_lost += 1
            return

        # Observable states:
        # 1. IDLE: _write_fut and _buffer both None

View on GitHub (pinned to bc6749cc3b)

Solutions

  1. Encode strings: transport.write(data.encode('utf-8'))
  2. Serialize structured data first: json.dumps(...).encode()
  3. For line protocols, use asyncio.StreamWriter.write() with bytes consistently; add an assertion/assert in debug builds

Example fix

# before
proc.stdin.write('hello\n')  # str -> TypeError

# after
proc.stdin.write(b'hello\n')
# or
proc.stdin.write('hello\n'.encode('utf-8'))
Defensive patterns

Strategy: type-guard

Validate before calling

if not isinstance(data, (bytes, bytearray, memoryview)):
    data = data.encode('utf-8') if isinstance(data, str) else bytes(data)

Type guard

def is_writable_bytes(data) -> bool:
    return isinstance(data, (bytes, bytearray, memoryview))

Prevention

When it happens

Trigger: transport.write('text') on a subprocess stdin or socket via proactor loop; writing a parsed JSON dict or int without encoding; on Windows (or macOS/Python 3.8+ defaults) where ProactorEventLoop/IOCP is the transport implementation.

Common situations: Code developed on Linux selector loop that also 'worked' with str in some paths; forgetting .encode('utf-8') for protocol messages; writing serialized objects directly; cross-platform apps hitting Windows CI for the first time.

Related errors


AI-assisted analysis of python/cpython@bc6749cc3b (2026-08-14). Data as JSON: /api/errors/e5e0f763a9290480. Report an issue: GitHub.