{"record":{"id":"30a5e49574abeee2","repo":"stride3d/stride","slug":"cannot-set-null-instance-of-virtualbutton","errorCode":null,"errorMessage":"Cannot set null instance of VirtualButton","messagePattern":"Cannot set null instance of VirtualButton","errorType":"validation","errorClass":"ArgumentNullException","httpStatus":null,"severity":"error","filePath":"sources/engine/Stride.Input/VirtualButton/VirtualButtonGroup.cs","lineNumber":29,"sourceCode":"    /// </summary>\n    public class VirtualButtonGroup : Collection<IVirtualButton>, IVirtualButton\n    {\n        public VirtualButtonGroup(bool isDisjunction = false)\n        {\n            IsDisjunction = isDisjunction;\n        }\n\n        /// <summary>\n        /// Gets or sets a value indicating whether this instance is determining the value as a disjunction ('&#124;&#124;' operator between buttons), false by default ('&amp;&amp;' operator).\n        /// </summary>\n        /// <value><c>true</c> if this instance is disjunction; otherwise, <c>false</c>.</value>\n        public bool IsDisjunction { get; set; }\n\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);","sourceCodeStart":11,"sourceCodeEnd":47,"githubUrl":"https://github.com/stride3d/stride/blob/96fad776d210c221682aac1ccdf4c79dc046fc38/sources/engine/Stride.Input/VirtualButton/VirtualButtonGroup.cs#L11-L47","documentation":"VirtualButtonGroup.InsertItem validates every item added to the group and throws ArgumentNullException when a null IVirtualButton is inserted. VirtualButtonGroup represents a set of button bindings, and a null entry would break grouping/matching logic downstream. The duplicate check (Contains) is only applied to non-null items.","triggerScenarios":"Adding null to a VirtualButtonGroup via Add(), collection initializer, or databinding that invokes InsertItem with a null item.","commonSituations":"Building a button-group asset/property grid where a binding slot was left empty; deserializing a group whose child button references failed to load (null entries in the collection).","solutions":["Remove or fix the null entry in the collection/initializer before calling Add on the group.","Filter out null items before populating the group.","Check the source asset/script for unassigned button references."],"exampleFix":"// before\ngroup.Buttons.Add(null); // crash\n// after\nif (button != null)\n    group.Buttons.Add(button);","handlingStrategy":"validation","validationCode":"if (buttons != null)\n    foreach (var b in buttons.Where(b => b != null))\n        group.Buttons.Add(b);","typeGuard":"bool IsValidButton(IVirtualButton b) => b != null;","tryCatchPattern":"try\n{\n    group.Buttons.Add(button);\n}\ncatch (ArgumentNullException)\n{\n    // Skip or log the null binding instead of adding it.\n}","preventionTips":["Initialize all virtual button references before building groups.","Filter nulls when deserializing button collections.","Use non-nullable references/enabled nullable checks to catch unassigned buttons at compile time."],"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"}