stride3d/stride · error · IndexOutOfRangeException

Invalid XInput device index

Error message

Invalid XInput device index {index}

What it means

InputSourceWindowsXInput.OpenDevice validates the gamepad index against XInputGamePadCount (4) and throws IndexOutOfRangeException for indices outside 0-3. XInput supports at most four controllers, and devices[] is only sized for valid indices.

Solutions

  1. Clamp or validate the index to 0..XInputGamePadCount-1 before calling OpenDevice.
  2. Map non-XInput devices to a different backend instead of forcing an XInput index.
  3. Fix loop bounds or saved-index logic in custom Scan/restore code.

Example fix

// before
inputSource.OpenDevice(deviceIndex); // may be > 3
// after
if (deviceIndex >= 0 && deviceIndex < 4)
    inputSource.OpenDevice(deviceIndex);
Defensive patterns

Strategy: validation

Validate before calling

if (index < 0 || index >= XInputGamePadCount)
    return; // or clamp: index = Math.Max(0, Math.Min(3, index));
inputSource.OpenDevice(index);

Type guard

bool IsValidXInputIndex(int i) => i >= 0 && i < 4;

Try / catch

try
{
    inputSource.OpenDevice(index);
}
catch (IndexOutOfRangeException)
{
    // Log the invalid index; skip this device.
}

Prevention

When it happens

Trigger: Calling OpenDevice with a negative index or an index >= XInputGamePadCount, typically from custom Scan logic or device-restore code that passes a stale/incorrect index.

Common situations: Restoring saved device configs that store raw driver indices; custom enumeration code mapping more than four devices to XInput; off-by-one loops over controllers.

Related errors


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

Appendix: source

Thrown at sources/engine/Stride.Input/Windows/InputSourceWindowsXInput.cs:107

                if (devices[i] == null)
                {
                    // Should register controller
                    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);
        }
    }
}

#endif

View on GitHub (pinned to 96fad776d2)