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 NoneView on GitHub (pinned to bc6749cc3b)
Solutions
- Encode strings: transport.write(data.encode('utf-8'))
- Serialize structured data first: json.dumps(...).encode()
- 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
- Encode all strings at the protocol boundary
- Standardize on bytes in write paths across platforms
- Test on Windows/proactor loops in CI to catch str writes
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
- Not implemented
- Failed to fetch glossary.json
- d3-flame-graph library failed to load
- {htmldir!r} is not a Sphinx HTML output directory
- Unknown thread safety level {level!r} for {name!r}. Valid le
AI-assisted analysis of python/cpython@bc6749cc3b (2026-08-14).
Data as JSON: /api/errors/e5e0f763a9290480.
Report an issue: GitHub.