# Changelog All notable changes to Bambuddy will be documented in this file. ## [0.2.5b2] - Unreleased ### Fixed - **`Ignore and Resume` now actually ignores the fault — wrong-plate HMS no longer re-pauses 1-2 s after click** — Symptom (continuation of #1869): clicking `Ignore and Resume` on a wrong-plate `0500_8051` HMS cleared the modal, the printer left PAUSE, then ~1-2 s later re-detected the wrong plate and re-paused with the identical HMS code — the modal popped back open and the user could not actually print on the "wrong" plate (the whole point of the Ignore button). **Root cause:** Bambuddy's `execute_hms_action` (`backend/app/services/bambu_mqtt.py:5496-5523`) redirected `IGNORE_RESUME` on `state == "PAUSE"` to a plain `resume` command, with a code comment claiming BambuStudio's "err-bearing shape" was "silently rejected by Bambu firmware" (verified during #1830). That diagnosis was wrong on two counts. (1) **`IGNORE_RESUME` doesn't map to `resume` at all in BambuStudio.** Source-of-truth from BambuStudio `src/slic3r/GUI/DeviceErrorDialog.cpp:600-602` and `src/slic3r/GUI/DeviceManager.cpp:1450-1462` (commit `4019d2e`): the button dispatches `command_hms_ignore`, whose wire shape is `{"print": {"command": "ignore", "err": "", "param": "reserve", "job_id": "", "sequence_id": "..."}}`. The firmware treats `command: "ignore"` as "suppress this check on the next attempt AND auto-resume the paused print" — semantically distinct from `command: "resume"` which means "I fixed the problem, re-check normally" and is exactly why the wrong-plate check re-fired. (2) **`err` is a DECIMAL string of the int, not the hex shortcode.** BambuStudio passes `std::to_string(m_error_code)` where `m_error_code` is the 32-bit `int` value of the print_error code — so for `0x05008051` the wire string is `"83918929"`, not `"05008051"`. The #1830 H2D test that "verified" the err-bearing shape was silently rejected almost certainly sent the hex string, which the firmware couldn't match against the active int fault → silent rejection looked like the entire shape was broken, when the actual problem was the format of one field. **Fix.** Replace the `hms_ignore(persistent)` helper with two distinct helpers matching BambuStudio's source: `hms_ignore_command()` publishes `command_hms_ignore`'s shape (`command: "ignore"`, decimal `err`, `param: "reserve"`, `job_id`); `hms_idle_ignore(persistent)` publishes `command_hms_idle_ignore`'s shape (`command: "idle_ignore"`, decimal `err`, `type: 0|1`). Wire `IGNORE_RESUME`, `IGNORE_NO_REMINDER_NEXT_TIME`, and `DONT_REMIND_NEXT_TIME` (alias) to `hms_ignore_command()` — BambuStudio routes all three to the same `command_hms_ignore` (`DeviceErrorDialog.cpp:596-602`), the "don't remind" half is the firmware's job. Wire `NO_REMINDER_NEXT_TIME` to `hms_idle_ignore(persistent=False)` — BambuStudio dispatches it via `command_hms_idle_ignore(..., 0)` (`DeviceErrorDialog.cpp:588-590`), distinct from the resume-bearing `ignore` command. The decimal-int conversion lives at the helper layer (`str(int(print_error, 16))` with a defensive fallback to the raw input on parse failure so the route can surface 502 rather than raising mid-dispatch). The `job_id=None` case sends an empty string, matching BambuStudio's `std::string` empty default. **Resume / stop unchanged** — the user has independently confirmed plain `resume` and plain `stop` work for `PROBLEM_SOLVED_RESUME` and `STOP_PRINTING` on their printer; BambuStudio's `command_hms_resume` / `command_hms_stop` do carry the same `err`+`param: "reserve"`+`job_id` fields, but changing a working shape without a field test risks regressing a path the user has confirmed, so the plain shape stays. The previous stale comments about "verified silently rejected" are removed and replaced with citations to BambuStudio's exact source lines. **Tests.** Six cases in `TestExecuteHmsActionDispatch` (`backend/tests/unit/services/test_hms_actions.py`) rewritten to assert the BambuStudio shape: `test_ignore_resume_sends_bambustudio_ignore_command_paused` pins the full payload (the exact #1869 trace), `test_ignore_resume_state_independent` confirms no PAUSE/RUNNING branch (BambuStudio's dispatch is unconditional), `test_ignore_no_reminder_uses_ignore_command_not_idle_ignore` pins the `DONT_REMIND_NEXT_TIME` → `command: "ignore"` route, `test_no_reminder_next_time_uses_idle_ignore_type_zero` pins the still-correct `NO_REMINDER_NEXT_TIME` → `idle_ignore` route (decimal `err` now), `test_ignore_accepts_16_char_full_code_as_decimal` covers the 64-bit hms[]-array fault shape, `test_ignore_with_no_job_id_sends_empty_string` pins the empty-string sentinel. 35/35 in `test_hms_actions.py`, 12/12 in HMS-touching `test_printers_api.py` integration cases, `ruff check` clean. **Scope.** Backend-only. Same modal, same API contract, same dispatch route — just a different MQTT command shape on the wire for the ignore branch. No DB migration, no permission, no i18n key. - **HMS error-modal action buttons look like buttons and stop falsely 502-ing on wrong-plate `Ignore and Resume`** — Two compounding issues in the HMS error modal surfaced when a user forced an HMS error for a wrong build plate and tried to dispatch the per-fault actions. (1) **Buttons read as inert badges.** The action `