Hacktoberfest 2026: the issues maintainers tagged for October, open and beginner-friendly. Browse Hacktoberfest issues

stlink_probe._get_board_id() raises TypeError, not KeyError, when mbed.htm exists but has no TargetID

Open Beginner friendly
#2,055 0 comments 0 reactions 0 assignees View on GitHub

Maintainers usually reply within 1 day

@alwaysmy is already working on this.

Since Oct 13, 2026.

  • #2056 by @alwaysmy — open

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.htm is 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

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from pyocd/pyOCD

All issues in pyocd/pyOCD

Similar issues

More Python issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.