dotnet/wpf · error · InvalidOperationException

SR.CannotChangeAfterSealed

Error message

SR.CannotChangeAfterSealed

What it means

InvalidOperationException from ConditionCollection.CheckSealed: the collection has been sealed (its owning trigger/style was sealed), after which modifications (Clear/Insert/Remove/Set) are no longer permitted, so any mutating call is rejected.

Solutions

  1. Add all conditions before the Style/Trigger is put into use (sealing happens on first use or explicit Seal)
  2. Create a new ConditionCollection instead of modifying a sealed one

Example fix

// before
appliedStyle.Triggers[0].Conditions.Clear(); // throws
// after
var newStyle = BuildStyleWithConditions();
button.Style = newStyle;
Defensive patterns

Strategy: validation

Validate before calling

if (conditions is ConditionCollection cc && cc.IsReadOnly)
    throw new InvalidOperationException("Collection is sealed; build a new style instead");

Try / catch

try { conditions.Clear(); }
catch (InvalidOperationException ex) { /* rebuild style/trigger and re-apply */ }

Prevention

When it happens

Trigger: Calling Clear(), Add/Insert, Remove, or this[index] setter on a ConditionCollection after its style was sealed (i.e., after the style was applied/used).

Common situations: Runtime edits to a trigger's condition collection on an applied style; shared application-level resources being mutated at runtime.

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 dotnet/wpf@81131a70a4 (2026-09-14). Data as JSON: /api/errors/7bfc581282d86ec7. Report an issue: GitHub.

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/ConditionCollection.cs:101

        {
            _sealed = true;

            // Seal all the conditions
            for (int i=0; i<Count; i++)
            {
                this[i].Seal(type);
            }
        }

        #endregion InternalMethods
        
        #region PrivateMethods

        private void CheckSealed()
        {
            if (_sealed)
            {
                throw new InvalidOperationException(SR.Format(SR.CannotChangeAfterSealed, "ConditionCollection"));
            }
        }
        
        private void ConditionValidation(object value)
        {
            ArgumentNullException.ThrowIfNull(value);

            Condition condition = value as Condition;
            if (condition == null)
            {
                throw new ArgumentException(SR.MustBeCondition);
            }
        }

        #endregion PrivateMethods

        #region Data
    

View on GitHub (pinned to 81131a70a4)