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

  1. Check for concurrent writers (OpenLogi GUI/agent, Logitech Options+) and close them before running the diagnostic.
  2. Re-run the diagnostic to see if the mode change is reproducible or a one-off race.
  3. Capture and restore the original mode around the write in the diagnostic.
  4. 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

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


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)