dotnet/wpf · error · ArgumentOutOfRangeException

SR.TemplateChildIndexOutOfRange

Error message

SR.TemplateChildIndexOutOfRange

What it means

TemplateChildIndex is stored internally as a 16-bit value where 0xFFFF encodes -1, so legal values are [-1, 65535]. The internal setter validates this and throws ArgumentOutOfRangeException(SR.TemplateChildIndexOutOfRange) for anything outside that range.

Solutions

  1. Reduce the number of nodes in the offending template below the 16-bit limit (split into nested templates/user controls)
  2. Regenerate the template if it was emitted by a tool producing excessive nodes
  3. Avoid writing TemplateChildIndex directly; let the framework assign it during template compilation
  4. If you own the generator, cap output size or emit nested FrameworkElementFactory hierarchies

Example fix

// before
// one generated template with 70000 nodes
// after
// split generation into StackPanel with child user controls, each < 65534 nodes
Defensive patterns

Strategy: validation

Validate before calling

if (childIndex < -1 || childIndex >= 0xFFFF) throw new ArgumentOutOfRangeException(nameof(childIndex));

Type guard

bool IsValidTemplateChildIndex(int i) => i is >= -1 and < 0xFFFF;

Try / catch

try { SetTemplateChildIndex(node, idx); }
catch (ArgumentOutOfRangeException) { /* template too large; split it */ }

Prevention

When it happens

Trigger: Internal/template infrastructure assigning TemplateChildIndex values >= 0xFFFF or < -1, typically when a compiled template contains more than 65534 template children or a corrupt index is computed.

Common situations: Extremely large generated templates (thousands of nodes) from code generation hitting the 16-bit cap; low-level template tooling or reflection-based code writing the index directly.

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


AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14). Data as JSON: /api/errors/bf000b77e9025cf4. Report an issue: GitHub.

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/FrameworkElement.cs:6238

            get
            {
                uint childIndex = (((uint)_flags2) & 0xFFFF);
                if (childIndex == 0xFFFF)
                {
                    return -1;
                }
                else
                {
                    return (int)childIndex;
                }
            }
            set
            {
                // We store TemplateChildIndex as a 16-bit integer with 0xFFFF meaning "-1".
                // Thus we support any indices in the range [-1, 65535).
                if (value < -1 || value >= 0xFFFF)
                {
                    throw new ArgumentOutOfRangeException(nameof(value), SR.TemplateChildIndexOutOfRange);
                }

                uint childIndex = (value == -1) ? 0xFFFF : (uint)value;

                _flags2 = (InternalFlags2)(childIndex | (((uint)_flags2) & 0xFFFF0000));
            }
        }

        internal bool IsRequestingExpression
        {
            get { return ReadInternalFlag2(InternalFlags2.IsRequestingExpression); }
            set { WriteInternalFlag2(InternalFlags2.IsRequestingExpression, value); }
        }

        internal bool BypassLayoutPolicies
        {
            get { return ReadInternalFlag2(InternalFlags2.BypassLayoutPolicies); }
            set { WriteInternalFlag2(InternalFlags2.BypassLayoutPolicies, value); }

View on GitHub (pinned to 81131a70a4)