dotnet/wpf · error · InvalidOperationException
SR.Format(SR.CannotChangeAfterSealed, "SetterBase")
Error message
SR.Format(SR.CannotChangeAfterSealed, "SetterBase")
What it means
SetterBase.CheckSealed throws InvalidOperationException once the setter's owning style/template has been sealed (made immutable after first use). This is WPF's immutability guard: sealed style objects cannot be modified, so any mutation after sealing fails with 'CannotChangeAfterSealed'.
Solutions
- Create a new Style/Setter instance (possibly BasedOn the original) instead of mutating the sealed one.
- If a style must be modified before use, do all mutations before applying it to any element.
- For shared mutable styles, keep an unsealed master copy and generate fresh styles per modification.
Example fix
// before var style = (Style)button.FindResource(typeof(Button)); style.Setters[0].Value = Brushes.Green; // sealed // after var newStyle = new Style(typeof(Button), style); newStyle.Setters.Add(new Setter(Control.BackgroundProperty, Brushes.Green)); button.Style = newStyle;
Defensive patterns
Strategy: try-catch
Validate before calling
if (setter.IsSealed) throw new InvalidOperationException("Create a new Setter instead of mutating"); Try / catch
try { setter.Value = newValue; }
catch (InvalidOperationException ex) when (ex.Message.Contains("CannotChangeAfterSealed")) { /* rebuild style */ } Prevention
- Treat styles and setters retrieved from applied elements as read-only
- Create derived styles with BasedOn instead of editing sealed ones
When it happens
Trigger: Modifying a Setter (Property or Value) after its style has been applied to an element or the style was sealed via style.Seal(); e.g. `setter.Value = x` on a setter retrieved from an applied style.
Common situations: Caching Style instances and mutating them later; tweaking a shared theme style at runtime; iterating Styles from FindResource and editing them.
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
- SR.Format(SR.CannotChangeAfterSealed, "EventTrigger")
- SR.Format(SR.CannotChangeAfterSealed…
- SR.Format(SR.CannotChangeAfterSealed, "Style")
- SR.CannotChangeAfterSealed
- SR.CannotChangeAfterSealed
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/d2366bd8fd0aa55c.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/SetterBase.cs:50
get
{
return _sealed;
}
}
internal virtual void Seal()
{
_sealed = true;
}
/// <summary>
/// Subclasses need to call this method before any changes to their state.
/// </summary>
protected void CheckSealed()
{
if ( _sealed )
{
throw new InvalidOperationException(SR.Format(SR.CannotChangeAfterSealed, "SetterBase"));
}
}
// Derived
private bool _sealed;
}
}
View on GitHub (pinned to 81131a70a4)