AprilNEA/OpenLogi · error
wheel inversion changed unexpectedly: was
Error message
wheel inversion changed unexpectedly: was {}, now {} What it means
The `openlogi` wheel diagnostic verifies that after writing a new scroll-wheel resolution, the device's HiResWheel mode is read back and every other wheel attribute is unchanged. This bail fires when the wheel's inversion flag changed between the pre-write read and the post-write read-back, which should be impossible for a resolution-only write. It indicates the device (or the write path) mutated an unrelated wheel setting, so the diagnostic refuses to report success.
Solutions
- Close other applications that may write HiResWheel settings (OpenLogi agent, Logitech Options+) and rerun the diagnostic so nothing mutates the wheel between reads.
- Read the wheel mode again with `openlogi diag wheel` (no --resolution) to see whether inversion is stable on the device; if it flips without any write, the firmware is misbehaving.
- Update OpenLogi (openlogi-hidpp / openlogi-hid) in case the write path has a known side-effect bug; report the device model/PID if it persists.
- If the inversion change is intentional on your device, note that this is a diagnostic strictness guard: run the wheel write through the GUI/agent path instead.
Defensive patterns
Strategy: validation
Validate before calling
// before running the diagnostic, snapshot and later compare manually:
let before = openlogi_hid::get_scroll_wheel_mode(&route).await?;
println!("inversion before: {}", before.inverted);
// after `set_scroll_resolution`:
let after = openlogi_hid::get_scroll_wheel_mode(&route).await?;
if after.inverted != before.inverted { eprintln!("device mutated inversion flag"); } Prevention
- Stop the OpenLogi agent and any vendor utility before running hardware diagnostics so nothing else writes wheel registers.
- Run the diagnostic twice when results look suspicious; a stable device reproduces identical inversion reads.
- Keep openlogi-hid/openlogi-hidpp updated so resolution writes are side-effect free.
- Report persistent inversion flips with device model and PID as a firmware/driver bug.
When it happens
Trigger: Running `openlogi diag wheel --resolution <value>` (or `--device NAME --resolution ...`) against a HID++ device (PID 0x2121) where `set_scroll_resolution` flips the device's inversion flag relative to the `before` snapshot — i.e. the device firmware applies side effects or the driver writes an unintended register.
Common situations: Firmware quirks where changing the resolution register also toggles the inversion bit; an out-of-date or buggy `openlogi-hid` write path; a device concurrently modified by the running OpenLogi agent, Logitech Options+, or another HID client mid-diagnostic.
Related errors
- SmartShift sensitivity write not applied: requested
- SmartShift mode changed unexpectedly: was
- SmartShift toggle had no effect: still
- wheel resolution write not applied: requested
- wheel reporting target is not native after write
AI-assisted analysis of AprilNEA/OpenLogi@e846e6f4b4 (2026-09-13).
Data as JSON: /api/errors/0340e3afd79aa62c.
Report an issue: GitHub.
Appendix: source
Thrown at crates/openlogi-cli/src/cmd/diag/wheel.rs:71
.await
.context("set wheel resolution")?;
print_mode("read-back", after);
if after.resolution != requested {
anyhow::bail!(
"wheel resolution write not applied: requested {}, device reports {}",
resolution_label(requested),
resolution_label(after.resolution)
);
}
if after.target != ScrollReportingTarget::Native {
anyhow::bail!(
"wheel reporting target is not native after write: {:?}",
after.target
);
}
if after.inverted != before.inverted {
anyhow::bail!(
"wheel inversion changed unexpectedly: was {}, now {}",
before.inverted,
after.inverted
);
}
println!(
"✓ wheel resolution set to {} (native reporting, inversion preserved)",
resolution_label(requested)
);
Ok(())
}
fn print_mode(label: &str, mode: ScrollWheelMode) {
println!(
" {label}: resolution={} inversion={} reporting={}",
resolution_label(mode.resolution),
if mode.inverted { "inverted" } else { "normal" },View on GitHub (pinned to e846e6f4b4)