seerge/g-helper · error · IOException

HID device was not found on your machine.

Error message

HID device was not found on your machine.

What it means

Thrown by the WindowsUsbProvider(vendorId, productId, path, timeout) constructor when it cannot find a matching HID device. HidSharp enumerates devices via DeviceList.Local.GetHidDevices(vendorId, productId); this overload selects a device with LINQ .First(x => x.DevicePath.Contains(path)), which throws InvalidOperationException when the filtered sequence is empty. A bare catch swallows that and rethrows it as IOException, hiding the real cause. This overload is used by peripherals (AsusMouse.SetProvider, AsusMouse.cs:537) to identify a device by VID/PID plus a device-path interface substring (e.g. 'mi_02&col01').

Source

Thrown at app/AnimeMatrix/Communication/Platform/WindowsUsbProvider.cs:20

using HidSharp;

namespace GHelper.AnimeMatrix.Communication.Platform
{
    internal class WindowsUsbProvider : UsbProvider
    {
        protected HidDevice HidDevice { get; }
        protected HidStream HidStream { get; }

        public WindowsUsbProvider(ushort vendorId, ushort productId, string path, int timeout = 500) : base(vendorId, productId)
        {
            try
            {
                HidDevice = DeviceList.Local.GetHidDevices(vendorId, productId)
                   .First(x => x.DevicePath.Contains(path));
            }
            catch
            {
                throw new IOException("HID device was not found on your machine.");
            }

            var config = new OpenConfiguration();
            config.SetOption(OpenOption.Interruptible, true);
            config.SetOption(OpenOption.Exclusive, false);
            config.SetOption(OpenOption.Priority, 10);
            HidStream = HidDevice.Open(config);
            HidStream.ReadTimeout = timeout;
            HidStream.WriteTimeout = timeout;
        }

        public WindowsUsbProvider(ushort vendorId, ushort productId, int maxFeatureReportLength, string name = "Matrix")
            : base(vendorId, productId)
        {
            try
            {
                HidDevice = DeviceList.Local
                    .GetHidDevices(vendorId, productId)

View on GitHub (pinned to b9ba417f1b)

Solutions

  1. Confirm the peripheral is connected, powered on, and visible in Windows Device Manager under Human Interface Devices.
  2. Verify the VID/PID passed to the constructor match the actual device (inspect with a HID enumeration tool or HidSharp DeviceList.Local.GetHidDevices).
  3. Print all candidate DevicePath strings for the VID/PID and confirm the 'path' substring matches one of them.
  4. Close other software that may hold the device exclusively (Armoury Crate, SignalRGB), then retry.
  5. Unplug and replug the device (or toggle it off/on) so HidSharp re-enumerates, then reconstruct the provider.
  6. Replace .First() with .FirstOrDefault() and a null check so the real reason (no path match) is reported instead of a generic message.

Example fix

// before
HidDevice = DeviceList.Local.GetHidDevices(vendorId, productId)
   .First(x => x.DevicePath.Contains(path));
// after
HidDevice = DeviceList.Local.GetHidDevices(vendorId, productId)
   .FirstOrDefault(x => x.DevicePath.Contains(path));
if (HidDevice is null)
    throw new IOException($"HID device VID=0x{vendorId:X4} PID=0x{productId:X4} path='{path}' was not found on your machine.");
Defensive patterns

Strategy: validation

Validate before calling

// Mirror the constructor's selection logic before building the provider.
bool IsMousePresent(ushort vid, ushort pid, string path) =>
    HidSharp.DeviceList.Local.GetHidDevices(vid, pid)
        .Any(d => d.DevicePath.Contains(path));

// Use it before constructing:
// if (!IsMousePresent(_vendorId, _productId, path)) { Logger.WriteLine("mouse not found"); return; }

Try / catch

// The constructor throws IOException on a missing device, so guard the caller:
try
{
    _usbProvider = new WindowsUsbProvider(_vendorId, _productId, path, USBTimeout());
}
catch (IOException ex)
{
    Logger.WriteLine($"{GetDisplayName()} connect failed: {ex.Message}");
    _usbProvider = null; // downstream Set/Get already null-check _usbProvider
}

Prevention

When it happens

Trigger: Constructing 'new WindowsUsbProvider(vendorId, productId, path, timeout)' when DeviceList.Local.GetHidDevices(vendorId, productId) returns either no devices, or devices whose DevicePath does not contain the supplied path substring. The internal .First() throws InvalidOperationException (sequence contains no elements); the catch converts it to IOException. It is NOT thrown by a feature-report-length mismatch (that is error [1]) nor by a failure to open the stream.

Common situations: The mouse/peripheral is disconnected, switched off, or asleep; the VID/PID hardcoded in the subclass do not match the plugged device; the device enumerated under a different HID interface so the path substring no longer matches; another program (e.g. Armoury Crate) holds the interface exclusively so HidSharp does not list it; USB cable/hub issue; HidSharp enumeration returned stale results right after a hot-plug. Developers also hit this after changing the path filter or port the device is plugged into.

Related errors


AI-assisted analysis of seerge/g-helper@b9ba417f1b (2026-08-13). Data as JSON: /api/errors/5d277298ab97854b. Report an issue: GitHub.