stride3d/stride · error · InvalidOperationException

Can not set more than one button at a time

Error message

Can not set more than one button at a time

What it means

GamePadSimulated.SetButton allows setting exactly one GamePadButton flag per call. The check (button & (button - 1)) != 0 fails when more than one bit is set in the flags value, so passing a combination like GamePadButton.A | GamePadButton.B throws InvalidOperationException. Passing GamePadButton.None (zero) also trips the check, since 0 & (0-1) == 0 is false — actually None passes, but any multi-flag value throws.

Solutions

  1. Call SetButton once per button instead of OR-ing flags together
  2. Iterate over the flags you need and issue one call per button
  3. Use a helper that splits a mask into individual flags and calls SetButton for each

Example fix

// before
simulatedPad.SetButton(GamePadButton.A | GamePadButton.B, true);
// after
simulatedPad.SetButton(GamePadButton.A, true);
simulatedPad.SetButton(GamePadButton.B, true);
Defensive patterns

Strategy: validation

Validate before calling

if (button != 0 && (button & (button - 1)) != 0)
    throw new ArgumentException("Set one button per SetButton call");

Prevention

When it happens

Trigger: Calling SetButton with a bitwise-OR of two or more GamePadButton flags, e.g. SetButton(GamePadButton.A | GamePadButton.B, true).

Common situations: Porting code that batches button states into a mask; loop code accumulating flags before a single SetButton call; misunderstanding the enum as a state mask rather than one-button-per-call API.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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

Appendix: source

Thrown at sources/engine/Stride.Input/Simulated/GamePadSimulated.cs:31

            ProductId = new Guid("B540474D-F8CC-4D27-B57E-7E87272FD9E6");
            Id = Guid.NewGuid();
            Source = source;
            State = new GamePadState();
        }

        public override string Name { get; }
        public override Guid Id { get; }
        public override IInputSource Source { get; }
        public override Guid ProductId { get; }
        public override GamePadState State { get; }

        private List<InputEvent> pendingEvents = new List<InputEvent>();

        public void SetButton(GamePadButton button, bool state)
        {
            // Check for only 1 bit
            if ((button & (button - 1)) != 0)
                throw new InvalidOperationException("Can not set more than one button at a time");

            var buttonEvent = InputEventPool<GamePadButtonEvent>.GetOrCreate(this);
            buttonEvent.Button = button;
            buttonEvent.IsDown = state;
            pendingEvents.Add(buttonEvent);
        }

        public void SetAxis(GamePadAxis axis, float value)
        {
            var axisEvent = InputEventPool<GamePadAxisEvent>.GetOrCreate(this);
            axisEvent.Axis = axis;
            axisEvent.Value = value;
            pendingEvents.Add(axisEvent);
        }

        public override void Update(List<InputEvent> inputEvents)
        {
            ClearButtonStates();

View on GitHub (pinned to 96fad776d2)