dotnet/wpf · error

Specified index is out of range or child at index is null…

Error message

Specified index is out of range or child at index is null. Do not call this method if VisualChildrenCount returns zero, indicating that the Visual has no children.

What it means

Panel.GetVisualChild throws ArgumentOutOfRangeException when the panel's _uiElementCollection is null (panel has no children) or the index is outside the actual child count. The Visual contract requires callers to honor VisualChildrenCount; requesting a child from an empty panel violates it.

Solutions

  1. Check VisualChildrenCount before calling GetVisualChild and iterate with index < count
  2. Use VisualTreeHelper.GetChild which respects the count contract instead of raw GetVisualChild
  3. Re-read the child count after any collection mutation rather than caching it
  4. Treat an empty panel (count 0) as having no children to enumerate

Example fix

// before
for (int i = 0; i <= panel.VisualChildrenCount; i++)
    var child = panel.GetVisualChild(i); // throws
// after
for (int i = 0; i < panel.VisualChildrenCount; i++)
    var child = VisualTreeHelper.GetChild(panel, i);
Defensive patterns

Strategy: validation

Validate before calling

int count = panel.VisualChildrenCount;
for (int i = 0; i < count; i++)
{
    var child = VisualTreeHelper.GetChild(panel, i);
}

Type guard

Visual GetChildSafe(Visual v, int i) =>
    (v is Panel p && i >= 0 && i < p.VisualChildrenCount) ? VisualTreeHelper.GetChild(v, i) : null;

Try / catch

try { var child = panel.GetVisualChild(index); }
catch (ArgumentOutOfRangeException) { /* panel empty or stale index; re-read VisualChildrenCount */ }

Prevention

When it happens

Trigger: Calling GetVisualChild(index) where index >= VisualChildrenCount or when the panel has no UIElementCollection; custom rendering/subclass code iterating children using a stale count; tooling/profiling code walking the visual tree with wrong bounds.

Common situations: Custom Panel subclasses overriding rendering and probing children directly; automation and UI-testing frameworks walking visuals during collection mutation; off-by-one loops (index <= Count instead of <).

Related errors


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

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Controls/Panel.cs:375

                if (_uiElementCollection == null)
                {
                    return 0;
                }
                else
                {
                    return _uiElementCollection.Count;
                }
            }
        }

        /// <summary>
        /// Gets the Visual child at the specified index.
        /// </summary>
        protected override Visual GetVisualChild(int index)
        {
            if (_uiElementCollection == null)
            {
                throw new ArgumentOutOfRangeException(nameof(index), index, SR.Visual_ArgumentOutOfRange);
            }

            if (IsZStateDirty) { RecomputeZState(); }
            int visualIndex = _zLut != null ? _zLut[index] : index;
            return _uiElementCollection[visualIndex];
        }

        /// <summary>
        /// Creates a new UIElementCollection. Panel-derived class can create its own version of
        /// UIElementCollection -derived class to add cached information to every child or to
        /// intercept any Add/Remove actions (for example, for incremental layout update)
        /// </summary>
        protected virtual UIElementCollection CreateUIElementCollection(FrameworkElement logicalParent)
        {
            return new UIElementCollection(this, logicalParent);
        }

        /// <summary>

View on GitHub (pinned to 81131a70a4)