{"record":{"id":"02f68157e890dad2","repo":"AprilNEA/OpenLogi","slug":"smartshift-mode-changed-unexpectedly-was-now","errorCode":null,"errorMessage":"SmartShift mode changed unexpectedly: was {:?}, now {:?}","messagePattern":"SmartShift mode changed unexpectedly: was (.+?), now (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/openlogi-cli/src/cmd/diag/smartshift.rs","lineNumber":63,"sourceCode":"            before.mode, before.auto_disengage\n        );\n\n        let after = openlogi_hid::set_smartshift_sensitivity(&route, requested)\n            .await\n            .context(\"set SmartShift sensitivity\")?;\n        println!(\n            \"  read-back: mode={:?} sensitivity={}\",\n            after.mode, after.auto_disengage\n        );\n\n        if after.auto_disengage != requested {\n            anyhow::bail!(\n                \"SmartShift sensitivity write not applied: requested {n}, device reports {}\",\n                after.auto_disengage\n            );\n        }\n        if after.mode != before.mode {\n            anyhow::bail!(\n                \"SmartShift mode changed unexpectedly: was {:?}, now {:?}\",\n                before.mode,\n                after.mode\n            );\n        }\n\n        println!(\n            \"✓ SmartShift sensitivity set to {n} (mode {:?} preserved)\",\n            after.mode\n        );\n        return Ok(());\n    }\n\n    let before = openlogi_hid::get_smartshift_status(&route)\n        .await\n        .context(\"read SmartShift status\")?;\n    println!(\n        \"  current: mode={:?} auto_disengage={} torque={}\",","sourceCodeStart":45,"sourceCodeEnd":81,"githubUrl":"https://github.com/AprilNEA/OpenLogi/blob/e846e6f4b4405e33bd6a9aaf949a482ce34cb6d8/crates/openlogi-cli/src/cmd/diag/smartshift.rs#L45-L81","documentation":"Raised by the SmartShift diagnostic when, after writing a new sensitivity value, the device's SmartShift mode (e.g. Free/Clicky via auto_disengage semantics) has changed compared to the value captured before the write. The diagnostic only intended to change sensitivity, so an unexpected mode change means the write touched more state than requested or the device is misbehaving. It guards against a diagnostic that silently corrupts unrelated device settings.","triggerScenarios":"Running the SmartShift sensitivity diagnostic where `after.mode != before.mode` after the sensitivity write — the set command or device firmware altered the mode field as a side effect, or another process wrote the mode concurrently.","commonSituations":"Firmware that resets mode when sensitivity crosses a boundary; concurrent writers (GUI app, another CLI instance) changing SmartShift mode mid-diagnostic; writing to the wrong HID++ register that overlaps mode state.","solutions":["Check for concurrent writers (OpenLogi GUI/agent, Logitech Options+) and close them before running the diagnostic.","Re-run the diagnostic to see if the mode change is reproducible or a one-off race.","Capture and restore the original mode around the write in the diagnostic.","Inspect the HID++ feature registers being written to ensure the sensitivity write cannot overlap mode state."],"exampleFix":"// before\nif after.mode != before.mode {\n    anyhow::bail!(\"SmartShift mode changed unexpectedly: was {:?}, now {:?}\", before.mode, after.mode);\n}\n// after\nlet mode_before = before.mode;\n// ... write sensitivity ...\nif after.mode != mode_before {\n    openlogi_hid::set_smartshift_mode(&route, mode_before).await?; // restore\n    anyhow::bail!(\"SmartShift mode changed unexpectedly: was {mode_before:?}, now {:?}\", after.mode);\n}","handlingStrategy":"try-catch","validationCode":"// Snapshot mode before the write and detect concurrent writers\nlet before = read_smartshift(&route).await?;\nassert_no_other_hidpp_clients()?; // e.g. check agent/Options+ not holding the device","typeGuard":null,"tryCatchPattern":"let result = run_smartshift_sensitivity_diag(&route, n).await;\nif let Err(e) = &result {\n    if e.to_string().contains(\"mode changed unexpectedly\") {\n        // restore original mode\n        let _ = set_smartshift_mode(&route, before.mode).await;\n    }\n}","preventionTips":["Snapshot all affected fields (mode + sensitivity) before any write.","Ensure no other process (GUI, agent, vendor software) writes SmartShift state concurrently.","Restore original state when a diagnostic detects collateral changes.","Run diagnostics on a quiet bus — no paired writes in flight."],"tags":["hardware","hidpp","smartshift","unexpected-state-change","diagnostics"],"backgroundTag":"unexpected-device-state-change","analyzedSha":"e846e6f4b4405e33bd6a9aaf949a482ce34cb6d8","analyzedAt":"2026-09-13T03:07:16.451Z","contentChangedAt":"2026-09-13T03:07:16.451Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}