{"record":{"id":"60f2e9bdb82449d2","repo":"stride3d/stride","slug":"not-a-valid-gamepad","errorCode":null,"errorMessage":"Not a valid gamepad","messagePattern":"Not a valid gamepad","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"sources/engine/Stride.Input/InputManager.cs","lineNumber":652,"sourceCode":"        /// Resets the <see cref=\"Sources\"/> collection back to it's default values\n        /// </summary>\n        public void ResetSources()\n        {\n            Sources.Clear();\n            AddSources();\n        }\n        \n        /// <summary>\n        /// Suggests an index that is unused for a given <see cref=\"IGamePadDevice\"/>\n        /// </summary>\n        /// <param name=\"gamePad\">The gamepad to find an index for</param>\n        /// <returns>The unused gamepad index</returns>\n        public int GetFreeGamePadIndex(IGamePadDevice gamePad)\n        {\n            if (gamePad == null)\n                throw new ArgumentNullException(nameof(gamePad));\n            if (!GamePads.Contains(gamePad))\n                throw new InvalidOperationException(\"Not a valid gamepad\");\n\n            // Find a new index for this game controller\n            int targetIndex = 0;\n            for (int i = 0; i < gamePadRequestedIndex.Count; i++)\n            {\n                var collection = gamePadRequestedIndex[i];\n                if (collection.Count == 0 || (collection.Count == 1 && collection[0] == gamePad))\n                {\n                    targetIndex = i;\n                    break;\n                }\n                targetIndex++;\n            }\n\n            return targetIndex;\n        }\n\n        private void AddSources()","sourceCodeStart":634,"sourceCodeEnd":670,"githubUrl":"https://github.com/stride3d/stride/blob/96fad776d210c221682aac1ccdf4c79dc046fc38/sources/engine/Stride.Input/InputManager.cs#L634-L670","documentation":"GetFreeGamePadIndex looks up a free index for a gamepad that must belong to the manager's GamePads collection. If the passed IGamePadDevice is not in GamePads, Stride throws InvalidOperationException because it cannot assign an index to a device it does not manage (null is rejected earlier with ArgumentNullException).","triggerScenarios":"Calling inputManager.GetFreeGamePadIndex with a gamepad instance obtained outside the manager (mock, detached device, or another manager's device).","commonSituations":"Unit tests using fake gamepads; a gamepad removed from GamePads (unplugged) before the index request; passing a stale cached device reference.","solutions":["Pass a gamepad from inputManager.GamePads rather than constructing your own.","Verify the gamepad is still connected: check GamePads.Contains(pad) before calling.","Re-fetch the device reference after connection changes instead of caching it."],"exampleFix":"// before\nvar idx = input.GetFreeGamePadIndex(new FakeGamePad());\n// after\nvar pad = input.GamePads.FirstOrDefault();\nvar idx = pad != null ? input.GetFreeGamePadIndex(pad) : -1;","handlingStrategy":"type-guard","validationCode":"bool IsValidPad(IGamePadDevice pad, InputManager input) => pad != null && input.GamePads.Contains(pad);","typeGuard":"IGamePadDevice GetManagedPad(InputManager input, IGamePadDevice pad) => input.GamePads.Contains(pad) ? pad : null;","tryCatchPattern":"try { var idx = input.GetFreeGamePadIndex(pad); }\ncatch (InvalidOperationException ex) when (ex.Message == \"Not a valid gamepad\") { idx = -1; }","preventionTips":["Only pass devices obtained from inputManager.GamePads.","Re-check GamePads.Contains after connection changes.","Use null checks plus Contains before calling."],"tags":["input","gamepad","invalid-argument"],"backgroundTag":"entity-not-found","analyzedSha":"96fad776d210c221682aac1ccdf4c79dc046fc38","analyzedAt":"2026-09-14T02:59:31.279Z","contentChangedAt":"2026-09-14T02:59:31.279Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}