dotnet/wpf · error · ArgumentOutOfRangeException

SR.TemplateChildIndexOutOfRange

Error message

SR.TemplateChildIndexOutOfRange

What it means

The internal TemplateChildIndex property on FrameworkContentElement throws ArgumentOutOfRangeException when set to a value below -1 or at/above 0xFFFF (65535). The index is stored in a 16-bit field where 0xFFFF encodes -1 (no template child), so only values in [-1, 65534] are representable.

Solutions

  1. Clamp or validate the index before assignment: if (idx < -1 || idx >= 0xFFFF) handle the error
  2. Use -1 (not -2 or other sentinels) to mean 'no template child'
  3. If more than 65534 template children are needed, restructure the template - the encoding cannot support it

Example fix

// before
el.TemplateChildIndex = childIndexFromList; // throws if childIndexFromList >= 65535

// after
if (childIndexFromList >= -1 && childIndexFromList < 0xFFFF)
    el.TemplateChildIndex = childIndexFromList;
else
    el.TemplateChildIndex = -1;
Defensive patterns

Strategy: validation

Validate before calling

if (index < -1 || index >= 0xFFFF)
    throw new ArgumentOutOfRangeException(nameof(index));
el.TemplateChildIndex = index;

Type guard

static bool IsValidTemplateChildIndex(int v) => v >= -1 && v < 0xFFFF;

Try / catch

try { el.TemplateChildIndex = idx; }
catch (ArgumentOutOfRangeException ex) { log.Error("TemplateChildIndex out of [-1, 65534]", ex); }

Prevention

When it happens

Trigger: Assigning TemplateChildIndex = -2, or any value >= 65535, when building/patching template child mappings programmatically.

Common situations: Custom template infrastructure or code generators that assign template child indices computed from large item counts; corruption/underflow in index bookkeeping.

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/b5ad43c8940e7185. Report an issue: GitHub.

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/FrameworkContentElement.cs:2099

            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); }
        }

        // Extracts the required flag and returns
        // bool to indicate if it is set or unset
        internal bool ReadInternalFlag(InternalFlags reqFlag)
        {

View on GitHub (pinned to 81131a70a4)