AprilNEA/OpenLogi · error

raw HID routes are outside HID++ fixture case capture

Error message

raw HID routes are outside HID++ fixture case capture

What it means

`derive_replay_route` only supports Bolt, Unifying, and Direct routes for HID++ fixture case capture. A RawHid route means the capture targeted a raw HID device outside the HID++ fixture model, so route derivation refuses instead of producing a meaningless fixture route.

Solutions

  1. Record the case against a HID++-capable device (check with `openlogi list` that it routes as Bolt/Unifying/Direct)
  2. If the device is HID++-capable but enumerated as RawHid, add/fix its driver metadata in openlogi-device-registry
  3. Skip fixture capture for genuinely raw-HID devices — they are outside this fixture model

Example fix

// before
openlogi fixture record-case --target rawhid:1234:5678
// after: target a HID++ device
openlogi fixture record-case --target direct:046d:b01e
Defensive patterns

Strategy: validation

Validate before calling

// confirm the target resolves to a HID++ route before capture
match route {
    DeviceRoute::Bolt{..} | DeviceRoute::Unifying{..} | DeviceRoute::Direct{..} => ok(),
    DeviceRoute::RawHid{..} => return Err("target is raw HID; not eligible for HID++ fixture capture"),
}

Type guard

fn is_hidpp_route(route: &DeviceRoute) -> bool {
    !matches!(route, DeviceRoute::RawHid { .. })
}

Prevention

When it happens

Trigger: Running fixture case capture/replay against a device whose route resolves to RawHid — e.g. recording a case for a non-HID++ (raw HID) device or a device enumerated without a HID++ driver mapping.

Common situations: Pointing the recorder at a device that exposes only a raw HID interface; a device missing from the openlogi-device-registry so it falls back to RawHid; a USB device in bootloader/DFU mode presenting a raw interface.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


AI-assisted analysis of AprilNEA/OpenLogi@e846e6f4b4 (2026-09-13). Data as JSON: /api/errors/5af9fd954281563c. Report an issue: GitHub.

Appendix: source

Thrown at crates/openlogi-cli/src/cmd/fixture/record_case/replay.rs:145

        DeviceRoute::Unifying { slot, .. } => {
            let value = unique_replacement(audit, SanitizedIdentityKind::ReceiverSerialNumber)?;
            if value.len() != 4 {
                bail!("sanitized Unifying receiver identity is not four bytes");
            }
            Ok(DeviceRoute::Unifying {
                receiver_uid: uppercase_hex(value),
                slot: *slot,
            })
        }
        DeviceRoute::Direct {
            vendor_id,
            product_id,
        } => Ok(DeviceRoute::Direct {
            vendor_id: *vendor_id,
            product_id: *product_id,
        }),
        DeviceRoute::RawHid { .. } => {
            bail!("raw HID routes are outside HID++ fixture case capture")
        }
    }
}

fn unique_replacement(audit: &HidCassetteAudit, kind: SanitizedIdentityKind) -> Result<&[u8]> {
    let mut replacements = audit
        .replacements
        .iter()
        .filter(|replacement| replacement.kind == kind);
    let value = replacements
        .next()
        .map(|replacement| replacement.synthetic_value.as_slice())
        .ok_or_else(|| anyhow::anyhow!("cassette audit has no sanitized receiver identity"))?;
    if replacements.next().is_some() {
        bail!("cassette audit has multiple sanitized receiver identities");
    }
    Ok(value)
}

View on GitHub (pinned to e846e6f4b4)