{"record":{"id":"2ff150b860ae3118","repo":"seerge/g-helper","slug":"name-control-device-was-not-found-on-your-machin","errorCode":null,"errorMessage":"{name} control device was not found on your machine.","messagePattern":"(.+?) control device was not found on your machine\\.","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"app/AnimeMatrix/Communication/Platform/WindowsUsbProvider.cs","lineNumber":44,"sourceCode":"            config.SetOption(OpenOption.Priority, 10);\n            HidStream = HidDevice.Open(config);\n            HidStream.ReadTimeout = timeout;\n            HidStream.WriteTimeout = timeout;\n        }\n\n        public WindowsUsbProvider(ushort vendorId, ushort productId, int maxFeatureReportLength, string name = \"Matrix\")\n            : base(vendorId, productId)\n        {\n            try\n            {\n                HidDevice = DeviceList.Local\n                    .GetHidDevices(vendorId, productId)\n                    .First(x => x.GetMaxFeatureReportLength() >= maxFeatureReportLength);\n                Logger.WriteLine($\"{name} Device: \" + HidDevice.DevicePath + \" \" + HidDevice.GetMaxFeatureReportLength());\n            }\n            catch\n            {\n                throw new IOException($\"{name} control device was not found on your machine.\");\n            }\n\n            var config = new OpenConfiguration();\n            config.SetOption(OpenOption.Interruptible, true);\n            config.SetOption(OpenOption.Exclusive, false);\n            config.SetOption(OpenOption.Priority, 10);\n\n            HidStream = HidDevice.Open(config);\n        }\n\n        public override void Set(byte[] data)\n        {\n            WrapException(() =>\n            {\n                HidStream.SetFeature(data);\n                HidStream.Flush();\n            });\n        }","sourceCodeStart":26,"sourceCodeEnd":62,"githubUrl":"https://github.com/seerge/g-helper/blob/b9ba417f1b822110ce41a1e152031a84bfa6ad80/app/AnimeMatrix/Communication/Platform/WindowsUsbProvider.cs#L26-L62","documentation":"Thrown by the WindowsUsbProvider(vendorId, productId, maxFeatureReportLength, name) constructor when no HID device with the given VID/PID reports a max feature report length at least maxFeatureReportLength. ASUS AniMe-matrix-style devices expose several HID interfaces; this overload selects the correct control interface by feature-report capacity using .First(x => x.GetMaxFeatureReportLength() >= maxFeatureReportLength). When nothing matches, .First() throws InvalidOperationException and the bare catch rethrows it as an IOException with the interpolated device name (e.g. 'Matrix control device was not found...'). Used by Device.SetProvider (Device.cs:44) for the AnimeMatrix communication device.","triggerScenarios":"Constructing 'new WindowsUsbProvider(vendorId, productId, maxFeatureReportLength, name)' when DeviceList.Local.GetHidDevices(vendorId, productId) returns devices but none has GetMaxFeatureReportLength() >= maxFeatureReportLength, or returns no devices at all. The threshold (e.g. >= 128 in SlashDevice.cs:150) is what distinguishes this overload from error [0], which keys on DevicePath instead. .First() throwing InvalidOperationException is the immediate trigger; the catch masks it.","commonSituations":"The laptop has no AniMe matrix hardware (the matrix-only product variant is absent); the matrix device is present but the driver is not exposing its feature report length; the device went to sleep or was disconnected; the machine is a non-supported ASUS model so the expected VID/PID is absent; HidSharp returned a stale/empty enumeration after suspend/resume; another process holds the interface. Developers hit this when reusing the provider on unsupported hardware or after a Windows update reset the HID driver.","solutions":["Confirm the machine actually has the AniMe matrix / supported device and that it appears in Device Manager as an HID device with the expected VID/PID (ASUS VID 0x0B05).","Enumerate all GetHidDevices(vendorId, productId) and log each GetMaxFeatureReportLength() to see whether any interface meets the threshold (mirrors the Logger.WriteLine already on line 40).","Lower or correct maxFeatureReportLength if the device interface changed across a firmware/driver revision.","Ensure no other application holds the control interface exclusively, then reconstruct the provider.","Treat a missing matrix device as a normal 'unsupported' condition rather than a fatal error (Device.SetProvider is virtual and already guarded with _usbProvider null checks downstream).","Switch .First() to .FirstOrDefault() with a null check so the message states which threshold failed."],"exampleFix":"// before\nHidDevice = DeviceList.Local.GetHidDevices(vendorId, productId)\n    .First(x => x.GetMaxFeatureReportLength() >= maxFeatureReportLength);\n// after\nHidDevice = DeviceList.Local.GetHidDevices(vendorId, productId)\n    .FirstOrDefault(x => x.GetMaxFeatureReportLength() >= maxFeatureReportLength);\nif (HidDevice is null)\n    throw new IOException($\"{name} control device (VID=0x{vendorId:X4} PID=0x{productId:X4}, featureReport >= {maxFeatureReportLength}) was not found on your machine.\");","handlingStrategy":"validation","validationCode":"// Mirror the constructor's feature-report-length filter before building the provider.\nbool IsMatrixPresent(ushort vid, ushort pid, int minFeatureReportLength) =>\n    HidSharp.DeviceList.Local.GetHidDevices(vid, pid)\n        .Any(d =>\n        {\n            try { return d.GetMaxFeatureReportLength() >= minFeatureReportLength; }\n            catch { return false; } // GetMaxFeatureReportLength can throw on some interfaces\n        });\n\n// Use it before constructing:\n// if (!IsMatrixPresent(_vendorId, _productId, _maxFeatureReportLength)) { return; }","typeGuard":null,"tryCatchPattern":"// Device.SetProvider constructs directly; wrap it to make absence non-fatal:\ntry\n{\n    _usbProvider = new WindowsUsbProvider(_vendorId, _productId, _maxFeatureReportLength, LogName);\n}\ncatch (IOException ex)\n{\n    Logger.WriteLine($\"{LogName} unavailable: {ex.Message}\");\n    _usbProvider = null;\n}","preventionTips":["Pre-check that an interface with GetMaxFeatureReportLength() >= the threshold exists before calling the constructor.","Wrap GetMaxFeatureReportLength() in try/catch during enumeration (see AsusHid.cs:228) because some HID interfaces throw when queried.","On non-AniMe hardware, short-circuit SetProvider so the throwing constructor is never reached.","Log every candidate device path and feature-report length (the constructor already does at line 40) to make absence diagnoses trivial.","Because Device.SetProvider is virtual and gated by 'if (_usbProvider is not null) return;', a one-time failed construction will not be retried automatically — re-invoke SetProvider explicitly after a device-changed event."],"tags":["hid","usb","hidsharp","hardware","windows","animematrix","device-enumeration","feature-report"],"backgroundTag":null,"analyzedSha":"b9ba417f1b822110ce41a1e152031a84bfa6ad80","analyzedAt":"2026-08-13T15:05:32.228Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}