stride3d/stride · error · InvalidOperationException
DirectInput GameController already opened
Error message
DirectInput GameController already opened {deviceInstance.InstanceGuid}/{deviceInstance.InstanceName} What it means
InputSourceWindowsDirectInput.OpenDevice throws InvalidOperationException when a DirectInput device with the same InstanceGuid is already present in the Devices dictionary. Scan enumerates devices repeatedly, and opening the same device twice would create duplicate controllers with conflicting state.
Solutions
- Check Devices.ContainsKey(deviceInstance.InstanceGuid) before calling OpenDevice.
- Ensure disconnected devices are removed from Devices before rescanning.
- Guard against concurrent/redundant Scan calls in custom input code.
Example fix
// before
inputSource.OpenDevice(deviceInstance);
// after
if (!inputSource.Devices.ContainsKey(deviceInstance.InstanceGuid))
inputSource.OpenDevice(deviceInstance); Defensive patterns
Strategy: validation
Validate before calling
if (!inputSource.Devices.ContainsKey(deviceInstance.InstanceGuid))
inputSource.OpenDevice(deviceInstance); Type guard
bool IsOpen(GameControllerDirectInput c, Guid instanceGuid) => c != null && inputSource.Devices.ContainsKey(instanceGuid);
Try / catch
try
{
inputSource.OpenDevice(deviceInstance);
}
catch (InvalidOperationException ex) when (ex.Message.StartsWith("DirectInput GameController already opened"))
{
// Device already tracked; ignore or refresh its state.
} Prevention
- Check the Devices dictionary before opening a device instance.
- Remove unplugged devices from Devices before rescanning.
- Serialize Scan calls; avoid overlapping scans on focus change and device arrival.
When it happens
Trigger: Scan() runs while Devices already contains an entry for deviceInstance.InstanceGuid — e.g. two Scan passes without removal, or a device re-enumerated after an unplug that was not deregistered.
Common situations: Plugging a controller in and out quickly so the removal queue lags behind rescan; window focus changes triggering rescan while the device is still registered; custom code calling Scan concurrently.
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
- Something should handle controller disconnect
- XInput device already opened
- Invalid XInput device index
- SDL GameController already opened
- Something should handle controller disconnect
AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14).
Data as JSON: /api/errors/b07d11bae474c43e.
Report an issue: GitHub.
Appendix: source
Thrown at sources/engine/Stride.Input/Windows/InputSourceWindowsDirectInput.cs:163
if (!Devices.ContainsKey(device.InstanceGuid))
{
OpenDevice(device);
}
}
}
/// <summary>
/// Opens a new game controller or gamepad
/// </summary>
/// <param name="deviceInstance">The device instance</param>
public void OpenDevice(DeviceInstance deviceInstance)
{
// Ignore XInput devices since they are handled by XInput
if (IsXInputDevice(deviceInstance.ProductGuid))
return;
if (Devices.ContainsKey(deviceInstance.InstanceGuid))
throw new InvalidOperationException($"DirectInput GameController already opened {deviceInstance.InstanceGuid}/{deviceInstance.InstanceName}");
GameControllerDirectInput controller;
try
{
controller = new GameControllerDirectInput(this, directInput, deviceInstance);
}
catch (SharpDXException)
{
// Some failure occured during device creation
return;
}
// Find gamepad layout
var layout = GamePadLayouts.FindLayout(this, controller);
if (layout != null)
{
// Create a gamepad wrapping around the controller
var gamePad = new GamePadDirectInput(this, inputManager, controller, layout);View on GitHub (pinned to 96fad776d2)