stride3d/stride · error · IndexOutOfRangeException
Gamepad index was out of range
Error message
Gamepad index was out of range
What it means
UnregisterGamePad frees the gamepad's slot in gamePadRequestedIndex. If gamePad.Index is negative or >= gamePadRequestedIndex.Count, the internal index table no longer matches the device and Stride throws IndexOutOfRangeException as an invariant failure rather than silently corrupting state.
Solutions
- Allocate indices only via InputManager.GetFreeGamePadIndex so Index stays in sync.
- Ensure each gamepad is unregistered exactly once (guard custom teardown code).
- Update Stride if the crash occurs during normal hot-plug with official backends.
Example fix
// before gamePad.Index = 0; // hand-assigned, out of sync with table // after var idx = inputManager.GetFreeGamePadIndex(gamePad); gamePad.RequestedIndex = idx;
Defensive patterns
Strategy: try-catch
Validate before calling
bool IndexValid(IGamePadDevice pad, int requestedIndexCount) => pad.Index >= 0 && pad.Index < requestedIndexCount;
Try / catch
try { /* unregister path runs internally */ }
catch (IndexOutOfRangeException ex) when (ex.Message == "Gamepad index was out of range")
{ logger.Warn(ex, "Stale gamepad index; forcing device list refresh"); } Prevention
- Assign indices only through GetFreeGamePadIndex.
- Unregister each gamepad exactly once.
- Keep Stride platform backends up to date for hot-plug fixes.
When it happens
Trigger: A gamepad with an out-of-sync Index (never allocated, or table shrunk) being unregistered; double-unregister of the same gamepad after its index was invalidated.
Common situations: Rapid connect/disconnect of controllers where a device is torn down twice; custom platform backends assigning Index without going through GetFreeGamePadIndex; shutdown ordering issues.
Related errors
- This GamePad's index can not be changed
- Not a valid gamepad
- Something should handle controller disconnect
- SDL GameController already opened
- Can not set more than one button at a time
AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14).
Data as JSON: /api/errors/2d8780f60dcd0bad.
Report an issue: GitHub.
Appendix: source
Thrown at sources/engine/Stride.Input/InputManager.cs:931
gamePads.Add(gamePad);
// Check if the gamepad provides an interface for assigning gamepad index
if (gamePad.CanChangeIndex)
{
gamePad.Index = GetFreeGamePadIndex(gamePad);
}
// Handle later index changed
gamePad.IndexChanged += GamePadOnIndexChanged;
UpdateGamePadRequestedIndices();
}
private void UnregisterGamePad(IGamePadDevice gamePad)
{
// Free the gamepad index in the gamepad list
// this will allow another gamepad to use this index again
if (gamePadRequestedIndex.Count <= gamePad.Index || gamePad.Index < 0)
throw new IndexOutOfRangeException("Gamepad index was out of range");
gamePadRequestedIndex[gamePad.Index].Remove(gamePad);
gamePads.Remove(gamePad);
gamePad.IndexChanged -= GamePadOnIndexChanged;
}
private void RegisterGameController(IGameControllerDevice gameController)
{
gameControllers.Add(gameController);
}
private void UnregisterGameController(IGameControllerDevice gameController)
{
gameControllers.Remove(gameController);
}
private void GamePadOnIndexChanged(object sender, GamePadIndexChangedEventArgs e)View on GitHub (pinned to 96fad776d2)