AprilNEA/OpenLogi · error
the selected direct-capture target does not match the…
Error message
the selected direct-capture target does not match the profile transport and slot; reconnect the same device and use the same --device selector
What it means
When finishing a contribution, `require_same_structural_route` compares the route of the currently selected device against the route recorded in the resumable profile, ignoring only receiver identity (UID/serial) but requiring the transport kind, slot, and for Direct/RawHid the vendor/product (and usage page/id) to match. A mismatch means the user reconnected a different device or used a different `--device` selector than in the original capture, which would mix identity material from two devices; the run is aborted.
Solutions
- Reconnect the exact same device in the same way as the original capture (same transport: receiver slot, Bluetooth, or wired)
- Use the same `--device` selector value as the original run — prefer a stable selector (VID:PID or serial) over a mutable numeric index
- Check `openlogi list` to confirm the device's current route matches the profile, then rerun the contribution
- If the setup legitimately changed, delete the resumable state and restart the contribution from scratch with the new device/transport
Example fix
// before: device moved to another receiver slot between sessions $ openlogi fixture contribute --id my-fixture --device 2 --output output/my-fixture Error: the selected direct-capture target does not match the profile transport and slot; ... // after: same device, same slot, same selector $ openlogi list # confirm device is back on the original slot/route $ openlogi fixture contribute --id my-fixture --device 1 --output output/my-fixture
Defensive patterns
Strategy: validation
Validate before calling
// Compare structural routes (transport + slot + vid/pid) before resuming
fn structural_matches(expected: &DeviceRoute, actual: &DeviceRoute) -> bool {
use DeviceRoute::*;
match (expected, actual) {
(Bolt { slot: a, .. }, Bolt { slot: b }) => a == b,
(Unifying { slot: a, .. }, Unifying { slot: b }) => a == b,
(Direct { vendor_id: v1, product_id: p1 }, Direct { vendor_id: v2, product_id: p2 }) => {
v1 == v2 && p1 == p2
}
(RawHid { vendor_id: v1, product_id: p1, .. }, RawHid { vendor_id: v2, product_id: p2, .. }) => {
v1 == v2 && p1 == p2
}
_ => false,
}
} Try / catch
match resume_result {
Err(e) if e.to_string().contains("does not match the profile transport and slot") => {
eprintln!("reconnect the same device / reuse the original --device selector");
}
other => other?,
} Prevention
- Record the device's stable selector (VID:PID or serial) at first capture and always reuse it for `--device`
- Avoid numeric `--device` indexes, which shift after replugs; prefer explicit VID:PID selectors
- Keep the device on the same receiver slot / transport for the whole contribution; don't move it mid-session
- Run `openlogi list` and compare the current route to the profile before resuming a contribution
When it happens
Trigger: Resuming `openlogi fixture contribute` (or finishing capture) after the device moved to a different receiver slot, was reconnected via a different transport (e.g. Bluetooth instead of the receiver, receiver instead of wired), or a different `--device` selector matched a device with different VID/PID/usage than the recorded profile.
Common situations: Unplugging and replugging the device into a different receiver slot or port between capture sessions; switching the device between Bolt/Unifying receiver and Bluetooth-direct; passing a numeric index to `--device` that now resolves to a different device after replug; capturing multiple similar devices (same vendor, different model/PID) and selecting the wrong one on resume.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- raw-HID devices support profile-only contributions
- the selected device has no stable synthetic identity for…
- resumable fixture cases contain a non-UTF-8 entry
- resumable fixture cases contain unexpected file
- fixture directory has no UTF-8 synthetic ID
AI-assisted analysis of AprilNEA/OpenLogi@e846e6f4b4 (2026-09-13).
Data as JSON: /api/errors/2b9eef372afe9342.
Report an issue: GitHub.
Appendix: source
Thrown at crates/openlogi-cli/src/cmd/fixture/contribute.rs:438
DeviceRoute::RawHid {
vendor_id: right_vendor,
product_id: right_product,
usage_page: right_page,
usage_id: right_usage,
..
},
) => {
left_vendor == right_vendor
&& left_product == right_product
&& left_page == right_page
&& left_usage == right_usage
}
_ => false,
};
if matches {
Ok(())
} else {
bail!(
"the selected direct-capture target does not match the profile transport and slot; \
reconnect the same device and use the same --device selector"
)
}
}
fn validate_args(args: &ContributeArgs) -> Result<()> {
if args.id.trim().is_empty() || matches!(args.id.as_str(), "." | "..") {
bail!("--id must be a nonempty synthetic path component");
}
if Path::new(&args.id).file_name() != Some(OsStr::new(&args.id))
|| args.id.contains('/')
|| args.id.contains('\\')
{
bail!("--id must be one synthetic path component without separators");
}
if args.name.trim().is_empty() {
bail!("--name must be a nonempty synthetic device name");View on GitHub (pinned to e846e6f4b4)