{"record":{"id":"b9f29c32e507d4b1","repo":"stride3d/stride","slug":"device-with-id-device-id-device-name-already-registered-to","errorCode":null,"errorMessage":"Device with Id {device.Id}({device.Name}) already registered to {devicesById[device.Id].Name}","messagePattern":"Device with Id (.+?)\\((.+?)\\) already registered to (.+?)","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"sources/engine/Stride.Input/InputManager.cs","lineNumber":795,"sourceCode":"        {\n            switch (e.Action)\n            {\n                case NotifyCollectionChangedAction.Add:\n                    OnInputDeviceAdded(source, (IInputDevice)e.Item);\n                    break;\n                case NotifyCollectionChangedAction.Remove:\n                    OnInputDeviceRemoved((IInputDevice)e.Item);\n                    break;\n                default:\n                    throw new InvalidOperationException(\"Unsupported collection operation\");\n            }\n        }\n\n        private void OnInputDeviceAdded(IInputSource source, IInputDevice device)\n        {\n            devices.Add(device);\n            if (!devicesById.TryAdd(device.Id, device))\n                throw new InvalidOperationException($\"Device with Id {device.Id}({device.Name}) already registered to {devicesById[device.Id].Name}\");\n\n            if (device is IKeyboardDevice)\n            {\n                RegisterKeyboard((IKeyboardDevice)device);\n                keyboards.Sort((l, r) => -l.Priority.CompareTo(r.Priority));\n            }\n            else if (device is IPointerDevice)\n            {\n                RegisterPointer((IPointerDevice)device);\n                pointers.Sort((l, r) => -l.Priority.CompareTo(r.Priority));\n            }\n            else if (device is IGameControllerDevice)\n            {\n                RegisterGameController((IGameControllerDevice)device);\n                gameControllers.Sort((l, r) => -l.Priority.CompareTo(r.Priority));\n            }\n            else if (device is IGamePadDevice)\n            {","sourceCodeStart":777,"sourceCodeEnd":813,"githubUrl":"https://github.com/stride3d/stride/blob/96fad776d210c221682aac1ccdf4c79dc046fc38/sources/engine/Stride.Input/InputManager.cs#L777-L813","documentation":"When a new input device is registered, its unique Device.Id is stored in devicesById. If a device with the same Id already exists, TryAdd fails and Stride throws InvalidOperationException reporting both device names, because duplicate device IDs would break device lookup and event routing.","triggerScenarios":"An input source (re)adding a device whose Id collides with an existing one — e.g. re-adding a device without a stable unique Id, or a custom source generating constant/zero Ids.","commonSituations":"Custom input sources hard-coding Device.Id; platform backends recreating a device after reconnect without freeing the old registration; two source instances emitting devices with identical Ids.","solutions":["Ensure every IInputDevice returns a unique, stable Id.","Remove the stale device (raise Remove on the source's Devices collection) before re-adding.","Fix duplicate/constant Id generation in custom sources."],"exampleFix":"// before\npublic Guid Id => Guid.Empty; // collides\n// after\npublic Guid Id => id; // unique per device instance, assigned at construction","handlingStrategy":"validation","validationCode":"if (existingDevicesById.TryGetValue(device.Id, out var dup) && !ReferenceEquals(dup, device)) throw new InvalidOperationException($\"Duplicate device Id {device.Id}\");","typeGuard":null,"tryCatchPattern":"try { /* register device */ }\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"already registered\"))\n{ logger.Error(ex, \"Duplicate device Id; removing stale device\"); }","preventionTips":["Generate unique, stable Guids for each device instance.","Never hard-code Device.Id in custom sources.","Remove stale device registrations before re-adding after reconnect."],"tags":["input","device-registration","duplicate-key"],"backgroundTag":"resource-already-exists","analyzedSha":"96fad776d210c221682aac1ccdf4c79dc046fc38","analyzedAt":"2026-09-14T02:59:31.279Z","contentChangedAt":"2026-09-14T02:59:31.279Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}