stride3d/stride · error · InvalidOperationException

Something should handle controller disconnect

Error message

Something should handle controller disconnect

What it means

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.

Solutions

  1. Subscribe to the controller's Disconnected event before scanning/opening devices.
  2. Restore the standard InputSourceWindowsDirectInput wiring that removes the device on disconnect.
  3. If using a custom input source, replicate the default handler that unregisters and disposes the controller.

Example fix

// before
var controller = new GameControllerDirectInput(this, directInput, deviceInstance);
// after
var controller = new GameControllerDirectInput(this, directInput, deviceInstance);
controller.Disconnected += (s, e) => RemoveDevice(controller);
Defensive patterns

Strategy: try-catch

Validate before calling

if (controller.Disconnected == null)
    controller.Disconnected += (s, e) => RemoveDevice(controller);

Type guard

bool HasDisconnectHandler(GameControllerDirectInput c) => c.Disconnected != null;

Try / catch

try
{
    inputSource.Update(events);
}
catch (InvalidOperationException ex) when (ex.Message.Contains("controller disconnect"))
{
    // Attach/repair the Disconnected handler and rescan devices.
}

Prevention

When it happens

Trigger: A DirectInput game controller is unplugged during Update() while no subscriber is registered on the controller's Disconnected event.

Common situations: 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.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14). Data as JSON: /api/errors/005c618863422060. Report an issue: GitHub.

Appendix: source

Thrown at sources/engine/Stride.Input/Windows/GameControllerDirectInput.cs:187

                var dirCount = state.PovControllers.Length < directionInfos.Count ? state.PovControllers.Length : directionInfos.Count;
                for (int i = 0; i < dirCount; i++)
                {
                    int povController = state.PovControllers[i];
                    HandleDirection(i, povController >= 0 ? Direction.FromTicks(povController, 36000) : Direction.None);
                }
            }
            catch (SharpDXException)
            {
                HandleDisconnect();
            }

            base.Update(inputEvents);
        }

        private void HandleDisconnect()
        {
            if (Disconnected == null)
                throw new InvalidOperationException("Something should handle controller disconnect");

            Disconnected.Invoke(this, null);
        }

        public class DirectInputAxisInfo : GameControllerAxisInfo
        {
            public int Offset;
        }
    }
}

#endif

View on GitHub (pinned to 96fad776d2)