{"record":{"id":"005c618863422060","repo":"stride3d/stride","slug":"something-should-handle-controller-disconnect-005c61","errorCode":null,"errorMessage":"Something should handle controller disconnect","messagePattern":"Something should handle controller disconnect","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"sources/engine/Stride.Input/Windows/GameControllerDirectInput.cs","lineNumber":187,"sourceCode":"                var dirCount = state.PovControllers.Length < directionInfos.Count ? state.PovControllers.Length : directionInfos.Count;\n                for (int i = 0; i < dirCount; i++)\n                {\n                    int povController = state.PovControllers[i];\n                    HandleDirection(i, povController >= 0 ? Direction.FromTicks(povController, 36000) : Direction.None);\n                }\n            }\n            catch (SharpDXException)\n            {\n                HandleDisconnect();\n            }\n\n            base.Update(inputEvents);\n        }\n\n        private void HandleDisconnect()\n        {\n            if (Disconnected == null)\n                throw new InvalidOperationException(\"Something should handle controller disconnect\");\n\n            Disconnected.Invoke(this, null);\n        }\n\n        public class DirectInputAxisInfo : GameControllerAxisInfo\n        {\n            public int Offset;\n        }\n    }\n}\n\n#endif\n","sourceCodeStart":169,"sourceCodeEnd":200,"githubUrl":"https://github.com/stride3d/stride/blob/96fad776d210c221682aac1ccdf4c79dc046fc38/sources/engine/Stride.Input/Windows/GameControllerDirectInput.cs#L169-L200","documentation":"GameControllerDirectInput.HandleDisconnect raises the Disconnected event, but if no handler is attached it throws InvalidOperationException with 'Something should handle controller disconnect'. The library treats an unhandled controller disconnect as a programming error because the device would otherwise silently vanish from the input system.","triggerScenarios":"A DirectInput game controller is unplugged during Update() while no subscriber is registered on the controller's Disconnected event.","commonSituations":"Custom input-source code constructing GameControllerDirectInput without wiring Disconnected; a change to InputSourceWindowsDirectInput skipping event subscription; hot-unplugging a joystick in a game using a custom/modified input pipeline.","solutions":["Subscribe to the controller's Disconnected event before scanning/opening devices.","Restore the standard InputSourceWindowsDirectInput wiring that removes the device on disconnect.","If using a custom input source, replicate the default handler that unregisters and disposes the controller."],"exampleFix":"// before\nvar controller = new GameControllerDirectInput(this, directInput, deviceInstance);\n// after\nvar controller = new GameControllerDirectInput(this, directInput, deviceInstance);\ncontroller.Disconnected += (s, e) => RemoveDevice(controller);","handlingStrategy":"try-catch","validationCode":"if (controller.Disconnected == null)\n    controller.Disconnected += (s, e) => RemoveDevice(controller);","typeGuard":"bool HasDisconnectHandler(GameControllerDirectInput c) => c.Disconnected != null;","tryCatchPattern":"try\n{\n    inputSource.Update(events);\n}\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"controller disconnect\"))\n{\n    // Attach/repair the Disconnected handler and rescan devices.\n}","preventionTips":["Always subscribe to Disconnected immediately after constructing a controller.","Use the stock InputSourceWindowsDirectInput rather than reimplementing device lifecycle.","Test games with controller hot-unplug scenarios."],"tags":["directinput","gamepad","event-handler","windows"],"backgroundTag":"invalid-state-transition","analyzedSha":"96fad776d210c221682aac1ccdf4c79dc046fc38","analyzedAt":"2026-09-14T02:59:31.279Z","contentChangedAt":"2026-09-14T02:59:31.279Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}