stride3d/stride · error · InvalidOperationException
XInput device already opened
Error message
XInput device already opened {index} What it means
InputSourceWindowsXInput.OpenDevice throws InvalidOperationException when devices[index] is already occupied, i.e. the gamepad at that XInput slot was already opened. Only one GamePadXInput may own a controller slot; opening a second would produce duplicate event streams.
Solutions
- Check devices[index] != null before calling OpenDevice.
- Wait for/trigger the pending devicesToRemove cleanup before reopening the slot.
- Close or dispose the existing GamePadXInput before opening a new one on the same index.
Example fix
// before
inputSource.OpenDevice(0);
inputSource.OpenDevice(0); // crash
// after
if (inputSource.Devices[0] == null)
inputSource.OpenDevice(0); Defensive patterns
Strategy: validation
Validate before calling
if (inputSource.Devices[index] == null)
inputSource.OpenDevice(index); Type guard
bool SlotIsFree(int i) => inputSource.Devices[i] == null;
Try / catch
try
{
inputSource.OpenDevice(index);
}
catch (InvalidOperationException ex) when (ex.Message.Contains("already opened"))
{
// Slot already in use; reuse the existing gamepad instead.
} Prevention
- Check the slot before opening; reuse the existing GamePadXInput instance.
- Flush pending devicesToRemove before rescanning.
- Route all open/close operations through one owner to avoid duplicate opens.
When it happens
Trigger: Calling OpenDevice(index) twice for the same slot without closing the first, or Scan running again while the device is still registered (devicesToRemove not yet processed).
Common situations: Rapid unplug/replug before the pending removal is flushed; manual double-open in custom gamepad management; concurrent Scan invocations.
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
- DirectInput GameController already opened
- Invalid XInput device index
- Something should handle controller disconnect
- SDL GameController already opened
- Something should handle controller disconnect
AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14).
Data as JSON: /api/errors/0dc802331cc66427.
Report an issue: GitHub.
Appendix: source
Thrown at sources/engine/Stride.Input/Windows/InputSourceWindowsXInput.cs:110
if (controllers[i].IsConnected)
{
OpenDevice(i);
}
}
}
}
/// <summary>
/// Opens a new gamepad
/// </summary>
/// <param name="instance">The gamepad</param>
public void OpenDevice(int index)
{
if (index < 0 || index >= XInputGamePadCount)
throw new IndexOutOfRangeException($"Invalid XInput device index {index}");
if (devices[index] != null)
throw new InvalidOperationException($"XInput device already opened {index}");
var newGamepad = new GamePadXInput(this, controllers[index], controllerIds[index], index);
newGamepad.Disconnected += (sender, args) =>
{
// Queue device for removal
devicesToRemove.Add(index);
};
devices[index] = newGamepad;
RegisterDevice(newGamepad);
}
}
}
#endifView on GitHub (pinned to 96fad776d2)