dotnet/wpf · error · InvalidOperationException
SR.Format(SR.TooManyDependencyProperties…
Error message
SR.Format(SR.TooManyDependencyProperties, "ConstantProperty")
What it means
Same global-index overflow as the ownerType variant, but raised when ownerType is null — i.e. the overflow occurred while registering something without an owner type, reported with the placeholder name "ConstantProperty". GlobalIndexCount exceeded GlobalIndexMask, so no unique global index can be assigned.
Solutions
- Reduce total number of registered DPs in the process; audit libraries doing dynamic registration
- Replace dynamic DP-per-item patterns with attached properties or plain dictionaries
- Profile with a debugger/ETW to find who registers tens of thousands of DPs and fix that library
Example fix
// before
// thousands of generated static types each Register-ing DPs at module load
var dp = DependencyProperty.Register(name, typeof(object), ownerType); // called in loop
// after
var valueCache = new Dictionary<object, object>(); // plain storage
// or a single attached property:
public static readonly DependencyProperty ValueProperty =
DependencyProperty.RegisterAttached("Value", typeof(object), typeof(Holder)); Defensive patterns
Strategy: validation
Validate before calling
// audit total DP registrations before adding more
if (Interlocked.Increment(ref registeredDpCount) > 32000)
throw new InvalidOperationException("Global DP index exhausted"); Try / catch
try { RegisterInternally(name, value); }
catch (InvalidOperationException) { /* overflow: degrade to non-DP storage */ } Prevention
- Audit plugin libraries that register DPs at load time
- Cap dynamic DP creation; use RegisterAttached once and key values yourself
- Monitor DP counts in long-running hosts
When it happens
Trigger: Exceeding ~32767 registered dependency properties in the AppDomain via a registration path that passes a null ownerType into GetUniqueGlobalIndex (internal constant/property registration paths).
Common situations: Same as the ownerType overflow: dynamic DP creation at scale, plugin systems, codegen frameworks; the null-owner variant usually indicates an internal registration path, so look at total DP counts in the process.
Understand the failure class
Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.
Related errors
- SR.Format(SR.TooManyDependencyProperties, ownerType.Name +…
- SR.Format(SR.InvalidPropertyValue, _value, _property.Name)
- SR.Format(SR.ReadOnlyDesignerCoersionNotAllowed, Name)
- SR.Format(SR.ReadOnlyOverrideNotAllowed, Name)
- SR.PropertyNotReadOnly
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/dc3648f65c8d6c98.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/WindowsBase/System/Windows/DependencyProperty.cs:1104
_packedData = packedData;
}
// Synchronized: Covered by DependencyProperty.Synchronized
internal static int GetUniqueGlobalIndex(Type ownerType, string name)
{
// Prevent GlobalIndex from overflow. DependencyProperties are meant to be static members and are to be registered
// only via static constructors. However there is no cheap way of ensuring this, without having to do a stack walk. Hence
// concievably people could register DependencyProperties via instance methods and therefore cause the GlobalIndex to
// overflow. This check will explicitly catch this error, instead of silently malfuntioning.
if (GlobalIndexCount >= (int)Flags.GlobalIndexMask)
{
if (ownerType != null)
{
throw new InvalidOperationException(SR.Format(SR.TooManyDependencyProperties, ownerType.Name + "." + name));
}
else
{
throw new InvalidOperationException(SR.Format(SR.TooManyDependencyProperties, "ConstantProperty"));
}
}
// Covered by Synchronized by caller
return GlobalIndexCount++;
}
/// <summary>
/// This is the callback designers use to participate in the computation of property
/// values at design time. Eg. Even if the author sets Visibility to Hidden, the designer
/// wants to coerce the value to Visible at design time so that the element doesn't
/// disappear from the design surface.
/// </summary>
internal CoerceValueCallback DesignerCoerceValueCallback
{
get { return _designerCoerceValueCallback; }
set
{View on GitHub (pinned to 81131a70a4)