AprilNEA/OpenLogi · error
capture failed with a host, open, disconnect, timeout…
Error message
capture failed with a host, open, disconnect, timeout, interruption, or non-replayable protocol error; no fixture was written
What it means
`ensure_replayable` validates that the just-recorded HID++ capture ended in a state the fixture replay machinery can reproduce. If the capture terminated via a host error, device-open failure, disconnect, timeout, interruption, or a non-replayable protocol result, the recording is discarded and this error is thrown instead of writing a fixture.
Solutions
- Re-run the record command with the device solidly connected (cable, or fresh receiver pairing) and let the capture finish without interruption
- Verify the recorded operation is expected to succeed on this device/firmware; if it returns a protocol error, record a different case or fix the device state first
- Stop competing consumers of the device (the OpenLogi agent or another CLI instance) so the open and I/O do not fail
- If timeouts recur, retry on a wired connection or a less congested wireless channel
Example fix
// before (flaky wireless capture) openlogi fixture record-case --name dpi-cycle # device dropped mid-run // after (stable capture) openlogi fixture record-case --name dpi-cycle # wired/direct, capture completes
Defensive patterns
Strategy: retry
Validate before calling
// before recording, ensure a stable device and no competing agent
let status = Command::new("openlogi").args(["list"]).output()?;
assert!(status.status.success(), "device not reachable; fix connection before recording"); Try / catch
match record_case_result {
Err(e) if e.to_string().contains("no fixture was written") => {
eprintln!("capture not replayable: {e}; re-record on a stable link");
}
Err(e) => return Err(e.into()),
Ok(fixture) => use_fixture(fixture),
} Prevention
- Record on a wired/direct connection when possible
- Stop the OpenLogi agent before recording
- Never unplug or let the device sleep during capture
- Only record operations the device supports and completes successfully
When it happens
Trigger: Running `openlogi fixture record-case` when the device disconnects mid-capture, the HID open fails, a request times out, the capture is interrupted, or the recorded HID++ operation result is not one of the replayable Ok states (e.g. a feature-error protocol result).
Common situations: Unplugging or powering off a mouse/receiver during recording; using a flaky Bolt/Unifying receiver link; recording a command whose protocol response is an error code rather than a replayable OK; another process holding the HID device so the open fails.
Understand the failure class
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
- read-only HID++ case capture unexpectedly opened a raw…
- no sanitized channel candidate reproduced the captured…
- raw HID routes are outside HID++ fixture case capture
- SmartShift sensitivity write not applied: requested
- SmartShift mode changed unexpectedly: was
AI-assisted analysis of AprilNEA/OpenLogi@e846e6f4b4 (2026-09-13).
Data as JSON: /api/errors/3c4e011e76f8a491.
Report an issue: GitHub.
Appendix: source
Thrown at crates/openlogi-cli/src/cmd/fixture/record_case.rs:174
}),
Self::FirmwareEntities(Err(error))
| Self::ReprogrammableControls(Err(error))
| Self::RawBattery(Err(error))
| Self::DpiInfo(Err(error))
| Self::SmartshiftStatus(Err(error))
| Self::WheelMode(Err(error))
| Self::BacklightState(Err(error)) => replayable_error(error),
Self::ReprogrammableControls(Ok(_))
| Self::RawBattery(Ok(_))
| Self::DpiInfo(Ok(_))
| Self::SmartshiftStatus(Ok(_))
| Self::WheelMode(Ok(_))
| Self::BacklightState(Ok(_)) => true,
};
if replayable {
Ok(())
} else {
bail!(
"capture failed with a host, open, disconnect, timeout, interruption, or \
non-replayable protocol error; no fixture was written"
)
}
}
}
fn replayable_error(error: &WriteError) -> bool {
matches!(
error,
WriteError::FeatureUnsupported { .. }
| WriteError::EmptyDpiList
| WriteError::HidppFeature { .. }
| WriteError::UnsupportedResponse { .. }
)
}
#[derive(Clone, Debug)]View on GitHub (pinned to e846e6f4b4)