stride3d/stride · error · InvalidOperationException

Tried to modify the configuration after is has been frozen.

Error message

Tried to modify the configuration after is has been frozen.

What it means

GestureConfig instances are frozen (via Freeze) once the recognizer is built; after that, CheckNotFrozen guards every setter. Modifying any configuration property after freezing throws InvalidOperationException 'Tried to modify the configuration after is has been frozen.'

Solutions

  1. Create a new GestureConfig (copy values) and modify the copy, then build a new recognizer
  2. Perform all configuration changes before CreateRecognizer / before the config is frozen
  3. Track a frozen flag in your own code and skip/batch updates after activation

Example fix

// before
frozenConfig.MinimumDragDistance = 20f; // throws
// after
var newConfig = new GestureConfig(frozenConfig); // or copy fields manually
newConfig.MinimumDragDistance = 20f;
var recognizer = newConfig.CreateRecognizer();
Defensive patterns

Strategy: try-catch

Validate before calling

// guard all property updates
if (!configFrozen) config.MinimumDragDistance = 20f;

Try / catch

try { config.MinimumDragDistance = 20f; }
catch (InvalidOperationException) { var copy = new GestureConfig(config); copy.MinimumDragDistance = 20f; }

Prevention

When it happens

Trigger: Setting RequiredNumberOfFingers, MinimumScaleValue, MinimumTranslationDistance, MinimumRotationAngle, MinimumDragDistance, or AllowedErrorMargins after the config was frozen — typically after CreateRecognizer or after the gesture system activated it.

Common situations: Attempting live tuning of gesture thresholds at runtime; reusing and mutating a shared frozen config for a new gesture; accidentally calling Freeze earlier than expected (e.g. on first use).

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


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

Appendix: source

Thrown at sources/engine/Stride.Input/Gestures/GestureConfig.cs:78

        private int requiredNumberOfFingers;

        /// <summary>
        /// Indicate that the configuration is frozen and cannot be modified anymore by the user.
        /// </summary>
        private bool frozen;

        /// <summary>
        /// Freeze the configuration so that the user cannot modify it anymore.
        /// </summary>
        private void Freeze()
        {
            frozen = true;
        }

        internal void CheckNotFrozen()
        {
            if (frozen)
                throw new InvalidOperationException("Tried to modify the configuration after is has been frozen.");
        }

        /// <summary>
        /// Create a recognizer for the current configuration.
        /// </summary>
        /// <returns></returns>
        internal GestureRecognizer CreateRecognizer(float screenRatio)
        {
            // freeze the configuration so that the user cannot modify it from outside.
            Freeze();

            return CreateRecognizerImpl(screenRatio);
        }

        internal abstract GestureRecognizer CreateRecognizerImpl(float screenRatio);
    }
}

View on GitHub (pinned to 96fad776d2)