AprilNEA/OpenLogi · error
SmartShift mode changed unexpectedly: was
Error message
SmartShift mode changed unexpectedly: was {:?}, now {:?} What it means
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.
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.
Example fix
// before
if after.mode != before.mode {
anyhow::bail!("SmartShift mode changed unexpectedly: was {:?}, now {:?}", before.mode, after.mode);
}
// after
let mode_before = before.mode;
// ... write sensitivity ...
if after.mode != mode_before {
openlogi_hid::set_smartshift_mode(&route, mode_before).await?; // restore
anyhow::bail!("SmartShift mode changed unexpectedly: was {mode_before:?}, now {:?}", after.mode);
} Defensive patterns
Strategy: try-catch
Validate before calling
// Snapshot mode before the write and detect concurrent writers let before = read_smartshift(&route).await?; assert_no_other_hidpp_clients()?; // e.g. check agent/Options+ not holding the device
Try / catch
let result = run_smartshift_sensitivity_diag(&route, n).await;
if let Err(e) = &result {
if e.to_string().contains("mode changed unexpectedly") {
// restore original mode
let _ = set_smartshift_mode(&route, before.mode).await;
}
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- SmartShift sensitivity write not applied: requested
- SmartShift toggle had no effect: still
- wheel reporting target is not native after write
- wheel resolution write not applied: requested
- wheel inversion changed unexpectedly: was
AI-assisted analysis of AprilNEA/OpenLogi@e846e6f4b4 (2026-09-13).
Data as JSON: /api/errors/02f68157e890dad2.
Report an issue: GitHub.
Appendix: source
Thrown at crates/openlogi-cli/src/cmd/diag/smartshift.rs:63
before.mode, before.auto_disengage
);
let after = openlogi_hid::set_smartshift_sensitivity(&route, requested)
.await
.context("set SmartShift sensitivity")?;
println!(
" read-back: mode={:?} sensitivity={}",
after.mode, after.auto_disengage
);
if after.auto_disengage != requested {
anyhow::bail!(
"SmartShift sensitivity write not applied: requested {n}, device reports {}",
after.auto_disengage
);
}
if after.mode != before.mode {
anyhow::bail!(
"SmartShift mode changed unexpectedly: was {:?}, now {:?}",
before.mode,
after.mode
);
}
println!(
"✓ SmartShift sensitivity set to {n} (mode {:?} preserved)",
after.mode
);
return Ok(());
}
let before = openlogi_hid::get_smartshift_status(&route)
.await
.context("read SmartShift status")?;
println!(
" current: mode={:?} auto_disengage={} torque={}",View on GitHub (pinned to e846e6f4b4)