dotnet/wpf · error · InvalidOperationException
SR.TypeMetadataCannotChangeAfterUse
Error message
SR.TypeMetadataCannotChangeAfterUse
What it means
The AffectsMeasure property setter throws InvalidOperationException when the metadata has been sealed. Once a dependency property is registered (or metadata is added via OverrideMetadata/AddOwner), WPF seals it so layout-related flags can no longer change; mutating them afterwards would invalidate already-computed layout information.
Solutions
- Set AffectsMeasure in the constructor or FrameworkPropertyMetadataOptions flags BEFORE passing the metadata to Register/OverrideMetadata/AddOwner.
- Create a fresh FrameworkPropertyMetadata instance with the desired options instead of mutating the sealed one.
- Check metadata.IsSealed before setting and fail fast with a clear message in debug builds.
Example fix
// before
FrameworkPropertyMetadata m = (FrameworkPropertyMetadata)MyProperty.GetMetadata(typeof(MyControl));
m.AffectsMeasure = true; // throws once sealed
// after
var m = new FrameworkPropertyMetadata(defaultValue, FrameworkPropertyMetadataOptions.AffectsMeasure);
DependencyProperty.Register("MyProperty", typeof(double), typeof(MyControl), m); Defensive patterns
Strategy: validation
Validate before calling
if (metadata.IsSealed)
throw new InvalidOperationException("Metadata already sealed; create a new FrameworkPropertyMetadata before setting AffectsMeasure."); Type guard
static bool CanModify(FrameworkPropertyMetadata m) => !m.IsSealed;
Try / catch
try { meta.AffectsMeasure = true; }
catch (InvalidOperationException ex) { log.Warn("Metadata sealed; recreate with FrameworkPropertyMetadataOptions.AffectsMeasure", ex); } Prevention
- Set all FrameworkPropertyMetadataOptions flags in the constructor, before Register/OverrideMetadata/AddOwner.
- Never mutate metadata returned from GetMetadata - always create a new instance.
- Register dependency properties and configure metadata together in static constructors.
When it happens
Trigger: Setting metadata.AffectsMeasure = true on a FrameworkPropertyMetadata instance after that metadata was passed to DependencyProperty.Register, OverrideMetadata, or AddOwner (i.e. after metadata.Sealed is true).
Common situations: Toggling AffectsMeasure at runtime in response to user settings; a static constructor order issue where another type's static initializer registered the metadata first; unit tests reusing a cached metadata object across registrations.
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.DefaultValueMayNotBeUnset
- SR.NoDefaultUpdateSourceTrigger
- SR.TypeMetadataCannotChangeAfterUse
- SR.TypeMetadataCannotChangeAfterUse
- " }} " element found. Expected fixed page element ( }} ).
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/56b3bc760c8bd208.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/FrameworkPropertyMetadata.cs:319
}
if (IsFlagSet(FrameworkPropertyMetadataOptions.SubPropertiesDoNotAffectRender, flags))
{
SubPropertiesDoNotAffectRender = true;
}
}
/// <summary>
/// Property affects measurement
/// </summary>
public bool AffectsMeasure
{
get { return ReadFlag(MetadataFlags.FW_AffectsMeasureID); }
set
{
if (IsSealed)
{
throw new InvalidOperationException(SR.TypeMetadataCannotChangeAfterUse);
}
WriteFlag(MetadataFlags.FW_AffectsMeasureID, value);
}
}
/// <summary>
/// Property affects arragement
/// </summary>
public bool AffectsArrange
{
get { return ReadFlag(MetadataFlags.FW_AffectsArrangeID); }
set
{
if (IsSealed)
{
throw new InvalidOperationException(SR.TypeMetadataCannotChangeAfterUse);
}View on GitHub (pinned to 81131a70a4)