stlink_probe._get_board_id() raises TypeError, not KeyError, when mbed.htm exists but has no TargetID
Maintainers usually reply within 1 day
Assessment
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Newbie friendliness
- 72/100
- Issue type
- Bug
- Clarity
- Clearly specified
- Activity status
- Active
- Tech stack
- python
- Domain
- embedded-iot
Research direction
Start in pyocd/probe/stlink_probe.py at the _get_board_id() lookup, around line 94, where info['target_id_mbed_htm'][0:4] is guarded only by except KeyError. Then check how stlink/detect/base.py stores target_id_mbed_htm as None. Done when a volume with an unparsable mbed.htm no longer aborts pyocd list, and the ST-Link shows n/a in the Target column.
Written by the indexing model from the issue text.
Description
Summary
StlinkProbe._get_board_id() raises an uncaught TypeError when an MSD volume contains an
mbed.htm whose TargetID cannot be parsed. Probe enumeration then aborts entirely, so
pyocd list prints one error line and exits 1 without listing any probe — including probes
that have nothing to do with the ST-Link.
The except KeyError guarding that line was added to fix #695, but it only covers the
"no mbed.htm file" case. The "file present but unparsable" case stores None in the same
key and raises TypeError, which slips past it.
Environment
- pyocd 0.36.0 on Windows, Python 3.14
- Behaviour is identical on 0.45.1 and current
main(checked by reading the released wheels
and the branch source) - ST-Link whose firmware does not answer
get_board_id() - A DAPLink MSD volume is also present, whose
mbed.htmis a redirect page with no TargetID
Symptom
PS> pyocd list
0002715 C Error: 'NoneType' object is not subscriptable [__main__]
No traceback by default (debug.traceback is off), exit code 1, no probe listed.
With -O debug.traceback=True:
File ".../pyocd/subcommands/list_cmd.py", line 94, in invoke
ConnectHelper.list_connected_probes()
File ".../pyocd/core/helpers.py", line 123, in list_connected_probes
ConnectHelper._print_probe_list(allProbes)
File ".../pyocd/core/helpers.py", line 283, in _print_probe_list
board_info = probe.associated_board_info
File ".../pyocd/probe/stlink_probe.py", line 142, in associated_board_info
if (self.board_id is not None) and (self.board_id in BOARD_ID_TO_INFO):
File ".../pyocd/probe/stlink_probe.py", line 73, in board_id
self._board_id = self._get_board_id()
File ".../pyocd/probe/stlink_probe.py", line 94, in _get_board_id
this_board_id = info['target_id_mbed_htm'][0:4]
TypeError: 'NoneType' object is not subscriptable
Root cause
stlink/detect/base.py stores None in the key whenever parsing fails:
htm_target_id, daplink_info = self._read_htm_ids(device["mount_point"])
if htm_target_id:
device["target_id"] = htm_target_id
else:
... # falls back to the USB id
device["target_id_mbed_htm"] = htm_target_id # None is stored here as well
_read_htm_ids() is documented to return None on failure, and _target_id_from_htm()
recognises only ?code=<hex> and ?auth=<hex>. A volume whose mbed.htm is just a redirect
page therefore yields target_id_mbed_htm = None while the key is always present.
stlink_probe.py guards only the key-absent case:
try:
this_board_id = info['target_id_mbed_htm'][0:4]
except KeyError:
so "key present, value None" escapes as TypeError.
Confirmed on this machine with the detector output for the single enumerated volume:
mount_point = 'D:'
target_id_mbed_htm = None <-- key present, value None
target_id_usb_id = '<hex>'
vendor_id / product_id = 0d28 / 0204
Amplification since 0.35.0
The loop slices for every enumerated MSD volume and only breaks on a matching usb_id,
so the offending volume does not need to belong to the ST-Link at all. Any volume with an
unparsable mbed.htm breaks enumeration of every ST-Link on the machine.
| version | usb_id gate before the slice |
exception caught | triggered here |
|---|---|---|---|
| 0.20.0 / 0.21.0 | yes | none | no |
| 0.22.0 – 0.34.3 | yes (the #695 fix) | KeyError |
no |
0.35.0 – 0.45.1, main |
removed | KeyError |
yes |
Suggested fix
Either is sufficient; the first is the smaller change.
except (KeyError, TypeError):
or stop storing None in base.py:
if htm_target_id is not None:
device["target_id_mbed_htm"] = htm_target_id
With the first fix applied locally, board_id returns None and pyocd list shows n/a
in the Target column for the ST-Link instead of losing the whole listing.
- Dominant language
- Python
- Stars
- 1.5k
- Forks
- 567
- Avg merge
- 2d 6h
- Merged PRs (30d)
- 20
Getting set up
- No Dockerfile or Docker Compose file
- No pull request template
- Read the contributing guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from pyocd/pyOCD
-
Difficulty 3/5 1-2 days Newbie friendliness 50/100
Maintainers usually reply within 1 day
-
Difficulty 3/5 Half a day Newbie friendliness 70/100
pyocd/pyOCD#2042 · 1 comment ·
Maintainers usually reply within 1 day
-
Difficulty 3/5 1-2 days Newbie friendliness 72/100
pyocd/pyOCD#2031 · 4 comments ·
Maintainers usually reply within 1 day
-
Difficulty 3/5 1-2 days Newbie friendliness 78/100
Maintainers usually reply within 1 day
-
nrf54lm20a: flash algorithm faults (IPSR=3) and 'pyocd reset' is a no-opPossibly taken A pull request linked to this issue is open or already merged. Open
Difficulty 4/5 3-5 days Newbie friendliness 48/100
Maintainers usually reply within 1 day
Similar issues
-
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
huggingface/sentence-transformers#4186 ·
Maintainers usually reply within 5 days
-
documentation good first issue
Difficulty 2/5 Half a day Newbie friendliness 72/100
sujithputta02/Esapay#13 ·
-
bot-triaged module: correctness (silent) module: mps module: NaNs and Infs triage review
Difficulty 2/5 Half a day Newbie friendliness 62/100
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 62/100
SCIInstitute/SCIRun#2842 ·
Maintainers usually reply within 3 days