stride3d/stride · error · ArgumentNullException

Cannot set null instance of VirtualButton

Error message

Cannot set null instance of VirtualButton

What it means

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.

Solutions

  1. Remove or fix the null entry in the collection/initializer before calling Add on the group.
  2. Filter out null items before populating the group.
  3. Check the source asset/script for unassigned button references.

Example fix

// before
group.Buttons.Add(null); // crash
// after
if (button != null)
    group.Buttons.Add(button);
Defensive patterns

Strategy: validation

Validate before calling

if (buttons != null)
    foreach (var b in buttons.Where(b => b != null))
        group.Buttons.Add(b);

Type guard

bool IsValidButton(IVirtualButton b) => b != null;

Try / catch

try
{
    group.Buttons.Add(button);
}
catch (ArgumentNullException)
{
    // Skip or log the null binding instead of adding it.
}

Prevention

When it happens

Trigger: Adding null to a VirtualButtonGroup via Add(), collection initializer, or databinding that invokes InsertItem with a null item.

Common situations: 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).

Related errors


AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14). Data as JSON: /api/errors/30a5e49574abeee2. Report an issue: GitHub.

Appendix: source

Thrown at sources/engine/Stride.Input/VirtualButton/VirtualButtonGroup.cs:29

    /// </summary>
    public class VirtualButtonGroup : Collection<IVirtualButton>, IVirtualButton
    {
        public VirtualButtonGroup(bool isDisjunction = false)
        {
            IsDisjunction = isDisjunction;
        }

        /// <summary>
        /// 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).
        /// </summary>
        /// <value><c>true</c> if this instance is disjunction; otherwise, <c>false</c>.</value>
        public bool IsDisjunction { get; set; }

        protected override void InsertItem(int index, IVirtualButton item)
        {
            if (item == null)
            {
                throw new ArgumentNullException("item", "Cannot set null instance of VirtualButton");
            }

            if (!Contains(item))
            {
                base.InsertItem(index, item);
            }
        }

        protected override void SetItem(int index, IVirtualButton item)
        {
            if (item == null)
            {
                throw new ArgumentNullException("item", "Cannot add null instance of VirtualButton");
            }

            if (!Contains(item))
            {
                base.SetItem(index, item);

View on GitHub (pinned to 96fad776d2)