{"record":{"id":"10078edad9a72584","repo":"stride3d/stride","slug":"cannot-add-null-instance-of-virtualbutton","errorCode":null,"errorMessage":"Cannot add null instance of VirtualButton","messagePattern":"Cannot add null instance of VirtualButton","errorType":"validation","errorClass":"ArgumentNullException","httpStatus":null,"severity":"error","filePath":"sources/engine/Stride.Input/VirtualButton/VirtualButtonGroup.cs","lineNumber":42,"sourceCode":"\n        protected override void InsertItem(int index, IVirtualButton item)\n        {\n            if (item == null)\n            {\n                throw new ArgumentNullException(\"item\", \"Cannot set null instance of VirtualButton\");\n            }\n\n            if (!Contains(item))\n            {\n                base.InsertItem(index, item);\n            }\n        }\n\n        protected override void SetItem(int index, IVirtualButton item)\n        {\n            if (item == null)\n            {\n                throw new ArgumentNullException(\"item\", \"Cannot add null instance of VirtualButton\");\n            }\n\n            if (!Contains(item))\n            {\n                base.SetItem(index, item);\n            }\n        }\n\n        /// <summary>\n        /// Implements the + operator.\n        /// </summary>\n        /// <param name=\"combination\">The combination.</param>\n        /// <param name=\"virtualButton\">The virtual button.</param>\n        /// <returns>The result of the operator.</returns>\n        public static VirtualButtonGroup operator +(VirtualButtonGroup combination, IVirtualButton virtualButton)\n        {\n            combination.Add(virtualButton);\n            return combination;","sourceCodeStart":24,"sourceCodeEnd":60,"githubUrl":"https://github.com/stride3d/stride/blob/96fad776d210c221682aac1ccdf4c79dc046fc38/sources/engine/Stride.Input/VirtualButton/VirtualButtonGroup.cs#L24-L60","documentation":"VirtualButtonGroup.SetItem validates items replaced at an index and throws ArgumentNullException when the replacement item is null. Like InsertItem, it keeps the group free of null bindings so button matching stays well-defined. The message says 'add' but the operation is an index-based set.","triggerScenarios":"Assigning group[index] = null or an indexer-based edit in a property grid that sets a binding slot to null.","commonSituations":"Editing bindings in the Game Studio property grid and clearing a slot; programmatic rebinding code that assigns an uninitialized button variable.","solutions":["Assign a valid IVirtualButton instance instead of null.","Remove the item via Remove/RemoveAt instead of setting it to null.","Initialize the button variable before the assignment."],"exampleFix":"// before\ngroup.Buttons[0] = null; // crash\n// after\ngroup.Buttons.RemoveAt(0);","handlingStrategy":"validation","validationCode":"if (newButton != null)\n    group.Buttons[index] = newButton;\nelse\n    group.Buttons.RemoveAt(index);","typeGuard":"bool CanReplace(IVirtualButton b) => b != null;","tryCatchPattern":"try\n{\n    group.Buttons[index] = newButton;\n}\ncatch (ArgumentNullException)\n{\n    group.Buttons.RemoveAt(index); // treat null as removal\n}","preventionTips":["Treat 'clear a binding' as RemoveAt, never as assigning null.","Validate editor/property-grid values before applying them to the group.","Enable nullable reference types on binding configuration code."],"tags":["virtual-button","null-argument","input"],"backgroundTag":"null-argument","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"}