dotnet/wpf · error · InvalidOperationException
SR.StyleHasTooManyElements
Error message
SR.StyleHasTooManyElements
What it means
Template child indices are stored in a 16-bit value; when a template's total number of named children would exceed 0xFFFF, WPF throws InvalidOperationException (StyleHasTooManyElements) instead of allocating an index that cannot be represented.
Solutions
- Reduce the number of named elements in the template (name only elements referenced by triggers/storyboards)
- Split into nested templates or use ItemsControl for repeated children instead of naming each
- Remove x:Name from decorative children; rely on visual-tree traversal instead
- Generate multiple templates so each stays under the index limit
Example fix
// before
for (int i = 0; i < 70000; i++)
StyleHelper.RegisterName(template, "child" + i, fe); // exceeds 0xFFFF
// after
const int MaxNamedChildren = 0xFFFF;
for (int i = 0; i < Math.Min(count, MaxNamedChildren); i++)
StyleHelper.RegisterName(template, "child" + i, fe); Defensive patterns
Strategy: validation
Validate before calling
static bool WithinIndexLimit(int namedChildren) => namedChildren <= 0xFFFF;
Try / catch
try { ApplyTemplate(); } catch (InvalidOperationException ex) when (ex.Message.Contains("too many")) { Log("Template exceeds 65535 named children"); UseLightweightTemplate(); } Prevention
- Name only elements that triggers/storyboards reference
- Use ItemsControl/virtualization for large repeated content
- Split giant templates into composed smaller templates
- Assert named-child count < 0xFFFF in template generation code
When it happens
Trigger: Registering a templated child name when frameworkTemplate.LastChildIndex >= 0xFFFF — i.e. a template with more than 65535 named children; unbounded programmatic child registration loops inside one template.
Common situations: Code-generated templates with enormous numbers of named children; pathological XAML generated from data with a name per item; flattened designs that give every descendant an x:Name.
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.ChildTemplateInstanceDoesNotExist
- SR.ElementMustBelongToTemplate
- SR.Format(SR.CannotChangeAfterSealed…
- SR.Format(SR.CannotChangeAfterSealed, "Template")
- SR.Format(SR.CannotHavePropertyInTemplate…
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/b6c572a696b96974.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/StyleHelper.cs:5323
HybridDictionary childIndexFromChildName;
int lastChildIndex;
Debug.Assert(frameworkTemplate != null);
childIndexFromChildName = frameworkTemplate.ChildIndexFromChildName;
lastChildIndex = frameworkTemplate.LastChildIndex;
if (childIndexFromChildName.Contains(childName))
{
throw new ArgumentException(SR.Format(SR.NameScopeDuplicateNamesNotAllowed, childName));
}
// Normal templated child check
// If we're about to give out an index that we can't support, throw.
if (lastChildIndex >= 0xFFFF)
{
throw new InvalidOperationException(SR.StyleHasTooManyElements);
}
// No index found, allocate
object value = lastChildIndex;
childIndexFromChildName[childName] = value;
Interlocked.Increment(ref lastChildIndex);
Debug.Assert(frameworkTemplate != null);
frameworkTemplate.LastChildIndex = lastChildIndex;
return (int)value;
}
//
// This method
// 1. Returns the ChildIndex for the given ChildName. If there isn't anView on GitHub (pinned to 81131a70a4)