{"record":{"id":"cac309bf3e111fe0","repo":"stride3d/stride","slug":"input-source-already-added","errorCode":null,"errorMessage":"Input Source already added","messagePattern":"Input Source already added","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"sources/engine/Stride.Input/InputManager.cs","lineNumber":597,"sourceCode":"        /// <summary>\n        /// Resume all input sources.\n        /// </summary>\n        public void Resume()\n        {\n            foreach (var source in Sources)\n            {\n                source.Resume();\n            }\n        }\n\n        private void SourcesOnCollectionChanged(object o, TrackingCollectionChangedEventArgs e)\n        {\n            var source = (IInputSource)e.Item;\n            switch (e.Action)\n            {\n                case NotifyCollectionChangedAction.Add:\n                    if (Sources.Count(x => x == source) > 1)\n                        throw new InvalidOperationException(\"Input Source already added\");\n\n                    EventHandler<TrackingCollectionChangedEventArgs> eventHandler = (sender, args) => InputDevicesOnCollectionChanged(source, args);\n                    devicesCollectionChangedActions.Add(source, eventHandler);\n                    source.Devices.CollectionChanged += eventHandler;\n                    source.Initialize(this);\n                    break;\n                case NotifyCollectionChangedAction.Remove:\n                    source.Dispose();\n                    source.Devices.CollectionChanged -= devicesCollectionChangedActions[source];\n                    devicesCollectionChangedActions.Remove(source);\n                    break;\n                default:\n                    throw new ArgumentOutOfRangeException(nameof(e.Action));\n            }\n        }\n\n        /// <summary>\n        /// Registers an input event type to process","sourceCodeStart":579,"sourceCodeEnd":615,"githubUrl":"https://github.com/stride3d/stride/blob/96fad776d210c221682aac1ccdf4c79dc046fc38/sources/engine/Stride.Input/InputManager.cs#L579-L615","documentation":"When the Sources tracking collection changes, the InputManager validates each Add and throws InvalidOperationException if the same IInputSource instance is already present (duplicated via Count > 1). Each source may only be initialized and subscribed once.","triggerScenarios":"Adding the same IInputSource instance to InputManager.Sources twice, e.g. calling Sources.Add(source) in code that runs again on scene reload or when Initialize is invoked twice.","commonSituations":"Game initialization re-run after reload; copy-pasted setup code adding a source in two places; sharing one source instance across multiple InputManagers.","solutions":["Add the source only once; guard with Sources.Contains(source) before Add.","Move source registration out of code that may re-execute (OnSceneLoad, Initialize).","Create a new IInputSource instance instead of re-adding a used one."],"exampleFix":"// before\nSources.Add(mySource); // may run twice\n// after\nif (!Sources.Contains(mySource)) Sources.Add(mySource);","handlingStrategy":"validation","validationCode":"if (!input.Sources.Contains(source)) input.Sources.Add(source);","typeGuard":null,"tryCatchPattern":"try { input.Sources.Add(source); }\ncatch (InvalidOperationException ex) when (ex.Message == \"Input Source already added\") { /* already registered: ignore */ }","preventionTips":["Guard Add with Contains when initialization may re-run.","Register sources in a single, idempotent startup path.","Never share one source instance between multiple InputManagers."],"tags":["input","duplicate-registration","invalid-state"],"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-15T23:17:13.987Z"}