commaai/openpilot · error · RuntimeError
chestnut disappeared before recovery
Error message
chestnut disappeared before recovery
What it means
RuntimeError at the top of rom_write(): the tool entered ROM-bootloader recovery but find_chestnut() now returns None - the device, which moments ago matched a ROM VID:PID (174c:2464/2463), has vanished from the USB bus before the recovery transfer could start. Recovery cannot proceed without a live ROM-bootloader endpoint.
Source
Thrown at openpilot/system/hardware/chestnut/flash.py:350
except FileExistsError as e:
backup = open(path, "rb").read()
if len(backup) != 0x100:
raise RuntimeError(f"invalid config backup: {path}") from e
if backup != data:
print(f"restoring config from {path}", flush=True)
return backup
with os.fdopen(fd, "wb") as f:
f.write(data)
f.flush()
os.fsync(f.fileno())
return data
def rom_write(image, config):
# the ROM bootloader implements only the BOT protocol, and requires a port reset before bulk transfers
path, _, _ = find_chestnut()
if path is None:
raise RuntimeError("chestnut disappeared before recovery")
unbind_drivers(path)
fd = open_device(path)
try:
fcntl.ioctl(fd, USBDEVFS_RESET)
finally:
os.close(fd)
time.sleep(3)
path, _, _ = find_chestnut()
if path is None:
raise RuntimeError("chestnut did not re-enumerate after reset")
fd = claim_interface(path, setup=True)
for ep in (0x02, 0x81):
fcntl.ioctl(fd, USBDEVFS_CLEAR_HALT, struct.pack("I", ep))
tag = 0
def bulk(ep, payload, timeout):
buf = ctypes.create_string_buffer(bytes(payload), len(payload))
fcntl.ioctl(fd, USBDEVFS_BULK, Bulk(ep, len(payload), timeout, ctypes.cast(buf, ctypes.c_void_p)))View on GitHub (pinned to 516ec1e682)
Solutions
- Check lsusb / /sys/bus/usb/devices for 174c:2464 - if absent, reseat cable and enclosure, wait for re-enumeration, re-run the tool
- Use a direct, well-seated connection; avoid hubs and marginal cables for recovery flashing
- Check VBUS regulation (/sys/kernel/debug/regulator/smb2-vbus/enable on the intended platform) if the enclosure is bus-powered
- Retry the tool end-to-end - ROM recovery is idempotent and rewrites the whole image
Defensive patterns
Strategy: validation
Validate before calling
from flash import find_chestnut
if find_chestnut()[0] is None:
raise SystemExit('device absent - reseat before starting ROM recovery') Try / catch
try:
rom_write(image, config)
except RuntimeError as e:
if 'disappeared' in str(e):
reseat_device(); rom_write(image, config) # idempotent, safe to restart Prevention
- Physically secure cables before starting recovery
- Verify the ROM device is present in lsusb right before invoking recovery
- Recovery is restartable - never panic-abort mid-recovery; let it retry
When it happens
Trigger: rom_write() called right after RomFallback was detected, but between detection and this scan the device disconnected: cable moved, enclosure lost power, VBUS dropped, or the device hard-crashed out of the bootloader.
Common situations: Loose USB-C connection jostled during recovery prep; power negotiation hiccup on the port; a hub dropping the device; enclosure powered from a marginal source; the ROM bootloader resetting itself once more after enumerating.
Related errors
- chestnut fell back to the ROM bootloader
- chestnut did not re-enumerate after reset
- chestnut did not enumerate within {timeout:g}s
- ROM flash command {cdb[0]:02x} {cdb[1]:02x} failed
- write failed: {e}
AI-assisted analysis of commaai/openpilot@516ec1e682 (2026-08-15).
Data as JSON: /api/errors/b827f3a8a39ca243.
Report an issue: GitHub.