commaai/openpilot · error · SerialException
write returned 0
Error message
write returned 0
What it means
Raised by Serial.write when os.write returns 0 bytes even though the fd accepted the call. POSIX writes of a nonzero buffer returning 0 indicate the driver consumed nothing, which this implementation treats as a hard error rather than looping forever.
Source
Thrown at openpilot/common/serial.py:175
def write(self, data: bytes) -> int:
self._ensure_open()
if not data:
return 0
view = memoryview(data)
total = 0
while total < len(data):
try:
n = os.write(self._fd, view[total:])
except InterruptedError:
continue
except OSError as e:
if e.errno in (errno.EAGAIN, errno.EWOULDBLOCK):
select.select([], [self._fd], [], None)
continue
raise SerialException(e.errno, f"write failed: {e}") from e
if n == 0:
raise SerialException("write returned 0")
total += n
return total
def flush(self) -> None:
self._ensure_open()
termios.tcdrain(self._fd)
def reset_input_buffer(self) -> None:
self._ensure_open()
termios.tcflush(self._fd, termios.TCIFLUSH)
def reset_output_buffer(self) -> None:
self._ensure_open()
termios.tcflush(self._fd, termios.TCOFLUSH)
def _close_fd(self) -> None:
if self._fd >= 0:
try:View on GitHub (pinned to 516ec1e682)
Solutions
- Verify you are not passing empty/zero-length byte slices to write()
- Reopen the serial port: the device is likely in a bad state
- Power-cycle the peripheral to reset its USB stack
Example fix
// before ser.write(payload[offset:]) # offset can equal len(payload) // after chunk = payload[offset:] if chunk: ser.write(chunk)
Defensive patterns
Strategy: validation
Validate before calling
def safe_write(ser, data: bytes) -> int:
if not data:
return 0
return ser.write(data) Try / catch
from common.serial import SerialException
try:
ser.write(chunk)
except SerialException as e:
if str(e) == 'write returned 0':
ser.close(); ser = Serial(devpath, baudrate)
else:
raise Prevention
- Never pass zero-length slices; guard slicing loops with 'if chunk:'
- Power-cycle the peripheral if writes consistently return 0
When it happens
Trigger: os.write(self._fd, view[total:]) returning 0, which can happen with a detached/defunct tty, a USB CDC device in a bad state, or an empty memoryview slipping past the initial 'if not data' guard (e.g., zero-length slice after total catches up).
Common situations: Device firmware crashed while still enumerated, writing a zero-length slice from a loop that advances total incorrectly, or a tty in a half-closed state after surprise removal.
Related errors
- write failed: {e}
- AT command timed out
- Failed to open ISD-R after retries
- could not open port {self._port}: {e}
- read failed: {e}
AI-assisted analysis of commaai/openpilot@516ec1e682 (2026-08-15).
Data as JSON: /api/errors/a7899835374c9d3b.
Report an issue: GitHub.