dotnet/wpf · error · ArgumentException
SR.Format(SR.DefaultValueMustBeFreeThreaded, propertyName)
Error message
SR.Format(SR.DefaultValueMustBeFreeThreaded, propertyName)
What it means
For properties whose type is DispatcherObject-derived, a default value carrying thread affinity (Dispatcher != null) cannot be shared across threads, and if it is neither free-threaded nor ISealable, WPF rejects it. Only free-threaded or sealable defaults are accepted so the metadata can be safely shared across all uses.
Solutions
- Freeze the default Freezable before putting it in metadata (call Freeze() so it becomes free-threaded).
- Use a shared static default created once and frozen.
- Choose a plain type without thread affinity (e.g. Color instead of SolidColorBrush) if possible.
Example fix
// before var brush = new SolidColorBrush(Colors.Red); new PropertyMetadata(brush); // after var brush = new SolidColorBrush(Colors.Red); brush.Freeze(); new PropertyMetadata(brush);
Defensive patterns
Strategy: validation
Validate before calling
if (defaultValue is DispatcherObject d && d.Dispatcher != null && defaultValue is not ISealable) throw new ArgumentException("Default must be free-threaded"); Type guard
static bool IsFreeThreadedDefault(object v) => v is not DispatcherObject d || d.Dispatcher == null || v is Freezable f && f.IsFrozen;
Prevention
- Freeze() Freezable defaults before storing them in metadata
- Create shared static defaults once and freeze them
- Prefer affinity-free types (Color, double) for defaults
When it happens
Trigger: Registering a property of type e.g. Brush/Geometry/Freezable-derived with a default instance that has a Dispatcher (created on the UI thread) and is not frozen/sealable in metadata.
Common situations: Passing a live UI-created Brush (e.g. new SolidColorBrush picked up from a control) as a default; defaults created on a background thread then used in multi-threaded scenarios.
Related errors
- Animation_CalculatedValueIsInvalidForProperty
- Animation_DependencyPropertyIsNotAnimatable
- InvalidOperationException()
- NotImplementedException
- SR.Animation_DependencyPropertyIsNotAnimatable
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/739f26fabbce8805.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/WindowsBase/System/Windows/DependencyProperty.cs:423
if (defaultValue is DispatcherObject dispatcherObject && dispatcherObject.Dispatcher != null)
{
// Try to make the DispatcherObject free-threaded if it's an
// ISealable.
if (dispatcherObject is ISealable valueAsISealable && valueAsISealable.CanSeal)
{
Invariant.Assert(!valueAsISealable.IsSealed,
"A Sealed ISealable must not have dispatcher affinity");
valueAsISealable.Seal();
Invariant.Assert(dispatcherObject.Dispatcher == null,
"ISealable.Seal() failed after ISealable.CanSeal returned true");
}
else
{
throw new ArgumentException(SR.Format(SR.DefaultValueMustBeFreeThreaded, propertyName));
}
}
}
// After checking for correct type, check default value against
// validator (when one is given)
if ( validateValueCallback != null &&
!validateValueCallback(defaultValue))
{
throw new ArgumentException(SR.Format(SR.DefaultValueInvalid, propertyName));
}
}
/// <summary>
/// Parameter validation for OverrideMetadata, includes code to force
/// all base classes of "forType" to register their metadata so we knowView on GitHub (pinned to 81131a70a4)