[Detail Bug] Configure panel shows stale programming checklist after switching devices
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 4
- Forks
- 0
- Avg merge
- 15h 38m
- Merged PRs (30d)
- 37
Description
Detail Bug Report
Introduced in #35 by @kewde on Sep 11, 2026
Summary
- Context:
ProgramSection(inapps/knx-gui/src/knx_gui/plugins/project/ui/components/program_section.py) renders the "Program Device" subsection of the Configure panel; it is a long-lived instance held byConfigurePaneland accumulates post-program status (_status,_checklist) baked-in with the active device'sindividual_addressat_starttime. - Bug: When the user switches the selected device via the
##device_selectcombo at the top of the Configure panel while a program operation is running, succeeded, or errored,ConfigurePanelresets only its own text buffers and never resetsProgramSection, so the next frame renders the new device's name next to the old device's stale checklist items. - Actual vs. expected: The panel header correctly reads
Program Device: <NewDevice>(it tracks the livedeviceargument), but the checklist row below it still claims[+] Write Individual Address <OldDevice.individual_address>— the only per-device label, baked in at_starttime. The other checklist rows are static strings (Waiting for a device in programming mode/Addressing device by serial number/Group Addresses / Parameters) and do not go stale. The section should either re-render with the new device's programming state (idle/find_device) or be reset to idle on device switch. - Impact: The defect is the mismatch between an accurate header and one stale row — the user sees
Program Device: DeviceBdirectly above[+] Write Individual Address 1.1.4(DeviceA's address), eroding trust in the panel's feedback. Most concerning when switching mid-program: the in-flight bus operation is still writing DeviceA's IA while the panel presents the result under DeviceB's name once the Future resolves.
Code with Bug
In apps/knx-gui/src/knx_gui/plugins/project/ui/configure.py, the device-change branch resets ConfigurePanel's own buffers but never touches ProgramSection:
if self._buffer_device_id != device.node_id:
self._name_buffer = device.name
self._sync_address_buffers(device.individual_address)
self._serial_buffer = ""
self._buffer_device_id = device.node_id # <-- BUG 🔴 no reset of self._program_section state/checklist
In apps/knx-gui/src/knx_gui/plugins/project/ui/components/program_section.py, stale checklist labels are rendered under the newly selected device name:
def _render_status(self, device: Device) -> None:
imgui.text(S.BTN_PROGRAM_DEVICE + f": {device.name}") # NEW device name
imgui.spacing()
for label, item_status in self._checklist: # STALE labels (old IA) <-- BUG 🔴 stale checklist rendered under new device's name
self._render_checklist_item(label, item_status)
The per-device checklist label is captured at request time and never re-evaluated:
if request.program_individual_address:
self._ia_checklist_index = len(self._checklist)
self._checklist.append(
(
S.PROGRAM_CHECKLIST_WRITE_IA.format(
address=device.individual_address # baked-in; not refreshed on device switch
),
"current",
)
)
Explanation
ConfigurePanel keeps a single ProgramSection instance for the lifetime of the panel. On device switch, ConfigurePanel updates its own buffers (name/address/serial) but does not reset ProgramSection’s state (_status, _checklist). ProgramSection._render_status() then uses the newly selected device for the header while rendering the previously constructed _checklist, which contains one device-specific label (Write Individual Address {address}) baked in at _start() time.
This is reproducible after a completed program (success/error), and also during an in-flight program because the device combo is always enabled; switching devices mid-program can lead to the old Future resolving later and updating ProgramSection while the panel is showing a different selected device.
Recommended Fix
Add a reset() method on ProgramSection to return it to its idle state (clear _checklist, _status, etc.) and call it from the ConfigurePanel device-change branch.
Additionally, guard against stale Future callbacks when switching devices mid-program by invalidating or ignoring callbacks from earlier starts (e.g., a generation token recorded at _start() and checked in _handle_future_done()).
History
This bug was introduced in commit 177a196. The commit added the ProgramSection sub-component to the Configure panel and, in the same diff, extended the existing device-change buffer-reset branch to clear the new _serial_buffer it introduced — but did not add any corresponding reset for the new stateful self._program_section, so the device-switch path that already reset ConfigurePanel's own buffers left ProgramSection's _status/_checklist intact. The commit is the true origin (not a move/rename): ProgramSection did not exist before this commit, and the only later commit touching configure.py (753ce7a, moving the Preview Memory button) does not touch the device-change branch. The author appears to have noticed the per-session _serial_buffer needed clearing on device switch but overlooked that the new sub-component held its own accumulated state.
Contributor guide
No contributing guide indexed for this repository
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.
Research direction
Start in apps/knx-gui/src/knx_gui/plugins/project/ui/configure.py at the device-change branch, then inspect ProgramSection in apps/knx-gui/src/knx_gui/plugins/project/ui/components/program_section.py, including _start(), _render_status(), and _handle_future_done(). Done means switching devices clears the old checklist and status, and an earlier operation cannot update the newly selected device's panel.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- frontend
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 75/100