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
- Confirm the peripheral is connected, powered on, and visible in Windows Device Manager under Human Interface Devices.
- Verify the VID/PID passed to the constructor match the actual device (inspect with a HID enumeration tool or HidSharp DeviceList.Local.GetHidDevices).
- Print all candidate DevicePath strings for the VID/PID and confirm the 'path' substring matches one of them.
- Close other software that may hold the device exclusively (Armoury Crate, SignalRGB), then retry.
- Unplug and replug the device (or toggle it off/on) so HidSharp re-enumerates, then reconstruct the provider.
- 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
- Pre-validate device presence with a GetHidDevices(...).Any(...) predicate before constructing the provider (AsusMouse.IsDeviceConnected at AsusMouse.cs:512 is the existing pattern to copy).
- Subscribe to HidSharp.DeviceList.Local.Changed to reconstruct providers only after a real enumeration event, avoiding stale-state construction.
- Never hardcode fragile path substrings without also logging all candidate DevicePath values when a device fails to match.
- Treat a missing peripheral as an expected runtime state, not an exceptional one: keep _usbProvider nullable and let Set/Get no-op (the base Device class already does this).
- Replace .First() with .FirstOrDefault() in the provider so a null check can produce a precise message instead of a swallowed InvalidOperationException.
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
- {name} control device was not found on your machine.
- Failed to get switchable graphics applications. Error code:
AI-assisted analysis of seerge/g-helper@b9ba417f1b (2026-08-13).
Data as JSON: /api/errors/5d277298ab97854b.
Report an issue: GitHub.