python/cpython · warning · TypeError
write() argument must be bytes-like, not
Error message
write() argument must be bytes-like, not {type(b).__name__} What it means
Debug-mode guard in BaseSelectorEventLoop.sock_recvfrom(): datagram receive via the loop requires a non-blocking socket, checked with gettimeout() != 0 whenever the loop is in debug mode. The check exists because the loop's readiness model assumes any recvfrom attempt can safely return EWOULDBLOCK instead of parking the whole thread.
Solutions
- sock.setblocking(False) immediately after creating the datagram socket
- Centralize socket creation for the loop in one factory that enforces non-blocking mode
- Keep blocking-timeout sockets away from sock_* APIs; use them only with synchronous or threaded I/O
Example fix
# before sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) await loop.sock_recvfrom(sock, 2048) # debug: ValueError # after sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) sock.setblocking(False) await loop.sock_recvfrom(sock, 2048)
Defensive patterns
Strategy: validation
Validate before calling
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.setblocking(False) # before first await
async def reader():
while True:
data, addr = await loop.sock_recvfrom(sock, 65536) Try / catch
try:
await loop.sock_recvfrom(sock, n)
except ValueError as e:
if 'non-blocking' in str(e):
sock.setblocking(False)
return await loop.sock_recvfrom(sock, n)
raise Prevention
- Always setblocking(False) on UDP sockets moved onto a loop
- Check blocking state when adopting sockets from third-party libs
- Avoid settimeout on sockets shared with the loop
- Test with debug-mode loops enabled to catch this early
When it happens
Trigger: await loop.sock_recvfrom(sock, bufsize) with debug mode on and a blocking socket or one carrying a nonzero timeout. Typical with UDP sockets created plainly (socket.socket(AF_INET, SOCK_DGRAM)) that never had setblocking(False) called.
Common situations: UDP services moved from a thread-per-socket design onto an event loop; sockets adopted from other libraries (dtls wrappers, monitoring agents) with timeouts set; CI running with asyncio debug fixtures enabled.
Related errors
- write() argument must be str, not
- A datagram socket was expected, got
- AIX_BUILDDATE is not defined or invalid
- Must run this script from the repo root
- Node can't be used without a value attribute.
AI-assisted analysis of python/cpython@bc6749cc3b (2026-08-14).
Data as JSON: /api/errors/eb065bba6cfdbd0c.
Report an issue: GitHub.
Appendix: source
Thrown at Lib/_android_support.py:126
class BinaryLogStream(io.RawIOBase):
def __init__(self, prio, tag, fileno=None):
self.prio = prio
self.tag = tag
self._fileno = fileno
def __repr__(self):
return f"<BinaryLogStream {self.tag!r}>"
def writable(self):
return True
def write(self, b):
if type(b) is not bytes:
try:
b = bytes(memoryview(b))
except TypeError:
raise TypeError(
f"write() argument must be bytes-like, not {type(b).__name__}"
) from None
# Writing an empty string to the stream should have no effect.
if b:
logcat.write(self.prio, self.tag, b)
return len(b)
# This is needed by the test suite --timeout option, which uses faulthandler.
def fileno(self):
if self._fileno is None:
raise io.UnsupportedOperation("fileno")
return self._fileno
# When a large volume of data is written to logcat at once, e.g. when a test
# module fails in --verbose3 mode, there's a risk of overflowing logcat's own
# buffer and losing messages. We avoid this by imposing a rate limit using theView on GitHub (pinned to bc6749cc3b)