Skip to content

fix: handle missing USB string descriptors in linux_list_serial_ports#95

Merged
puddly merged 2 commits into
puddly:devfrom
StefCoene:fix/missing-usb-string-descriptors
May 20, 2026
Merged

fix: handle missing USB string descriptors in linux_list_serial_ports#95
puddly merged 2 commits into
puddly:devfrom
StefCoene:fix/missing-usb-string-descriptors

Conversation

@StefCoene
Copy link
Copy Markdown
Contributor

Problem

USB devices are not required to provide manufacturer, product, or serial number string descriptors (indicated by index 0 in the USB device descriptor). When these descriptors are absent, the corresponding sysfs files (serial, manufacturer, product) do not exist under /sys/bus/usb/devices/<device>/.

Previously, these fields were read directly with .read_text() inside the SerialPortInfo(...) constructor call, outside the try/except OSError block. A missing sysfs file raises FileNotFoundError (a subclass of OSError), which was caught by the outer except OSError: continue, causing the entire device to be silently skipped.

Affected device

Velleman VMB1USB (VID: 10cf, PID: 0b1b) — a CDC-ACM USB serial interface without a USB serial number descriptor. The device appears correctly in /dev/serial/by-id/, /sys/class/tty/, and is detected by pyserial, but was invisible to serialx.list_serial_ports().

This caused the device to not appear in the Home Assistant Velbus integration USB port selector, which uses serialx via homeassistant.components.usb.async_scan_serial_ports().

Fix

Add a _read_optional_sysfs() helper that returns None on OSError instead of raising. Use it for the three optional USB string descriptor fields (serial_number, manufacturer, product) in both the usb-serial and usb (CDC-ACM) subsystem branches.

Mandatory fields (idVendor, idProduct, bcdDevice, bInterfaceNumber) remain in the existing try/except block that handles devices disappearing during iteration.

This mirrors the existing pattern already used for interface_description, which was already handled with an explicit .exists() check.

USB devices are not required to provide manufacturer, product, or serial
number string descriptors (indicated by index 0 in the USB device
descriptor). When these descriptors are absent the corresponding sysfs
files do not exist, causing read_text() to raise FileNotFoundError.

Previously the entire OSError catch block skipped the device with
`continue`, so any device without a serial number (a common case) was
silently excluded from the port list.

Fix by reading the optional fields via _read_optional_sysfs(), which
returns None on OSError, while keeping mandatory fields (vid, pid,
bcd_device, interface_num) in the existing try/except that skips
devices that disappear during iteration.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@puddly
Copy link
Copy Markdown
Owner

puddly commented May 20, 2026

Thanks!

Could you run umockdev --all and add the output to a file tests/data/linux? It snapshots your system state in a way that can be "replayed" for unit tests. I don't believe the file contains any sensitive info but double check to be sure.

@codecov
Copy link
Copy Markdown

codecov Bot commented May 20, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 91.52%. Comparing base (b068974) to head (e530e3a).

Additional details and impacted files
@@            Coverage Diff             @@
##              dev      #95      +/-   ##
==========================================
+ Coverage   91.46%   91.52%   +0.05%     
==========================================
  Files          22       22              
  Lines        3599     3610      +11     
==========================================
+ Hits         3292     3304      +12     
+ Misses        307      306       -1     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Comment thread serialx/platforms/serial_linux.py
Comment thread serialx/platforms/serial_linux.py
@StefCoene
Copy link
Copy Markdown
Contributor Author

Could you run umockdev --all and add the output to a file tests/data/linux? It snapshots your system state in a way that can be "replayed" for unit tests. I don't believe the file contains any sensitive info but double check to be sure.

If I understand correctly, umockdev should be run on HA?
That's a bit tricky since I don't have ssh access, only console access.

Stef

@StefCoene
Copy link
Copy Markdown
Contributor Author

Could you run umockdev --all and add the output to a file tests/data/linux? It snapshots your system state in a way that can be "replayed" for unit tests. I don't believe the file contains any sensitive info but double check to be sure.

If I understand correctly, umockdev should be run on HA? That's a bit tricky since I don't have ssh access, only console access.
Update to my own reply, I can attach the device to an other VM (HA is running as VM on QNAP and execute the umockdev on that VM.
I will do that this evening and post the result.

Stef

@puddly
Copy link
Copy Markdown
Owner

puddly commented May 20, 2026

Ah, I didn't realize this was with Home Assistant OS. Ignore me 😄

@puddly puddly merged commit 4508439 into puddly:dev May 20, 2026
22 checks passed
@StefCoene StefCoene deleted the fix/missing-usb-string-descriptors branch May 20, 2026 19:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants