stride3d/stride · error · ArgumentNullException

Value cannot be null. (Parameter 'getChildFunc')

Error message

Value cannot be null. (Parameter 'getChildFunc')

What it means

FindChildOfType<T> throws ArgumentNullException when the getChildFunc delegate is null. This delegate supplies each child by index during the tree walk; without it the search cannot proceed, so the method validates it eagerly at entry.

Solutions

  1. Pass a non-null child accessor such as VisualTreeHelper.GetChild or LogicalTreeHelper.GetChild.
  2. Verify the two delegates are not swapped: count func is (DependencyObject,int)->int, child func is (DependencyObject,int,DependencyObject).
  3. If delegates are built dynamically, assert non-null before calling.
  4. Provide a fallback accessor instead of null when the tree helper is unavailable.

Example fix

// before
var child = FindChildOfType<Button>(root, VisualTreeHelper.GetChildrenCount, null);
// after
var child = FindChildOfType<Button>(root, VisualTreeHelper.GetChildrenCount, VisualTreeHelper.GetChild);
Defensive patterns

Strategy: validation

Validate before calling

if (getChildFunc == null) throw new InvalidOperationException("getChildFunc is null");

Type guard

static bool IsValidAccessors(Func<DependencyObject,int> count, Func<DependencyObject,int,DependencyObject> get) => count != null && get != null;

Try / catch

try { return FindChildOfType<Button>(root, count, get); }
catch (ArgumentNullException ex) when (ex.ParamName == "getChildFunc") { return null; }

Prevention

When it happens

Trigger: Invoking FindChildOfType (directly or via a public wrapper) with a null child-accessor delegate while source and getChildrenCountFunc are non-null.

Common situations: Passing null for an optional-feeling parameter; mixing up the order of the two Func arguments (count func vs child func); a factory expression returning null on some code path.

Related errors


AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14). Data as JSON: /api/errors/ba1f54592b85440e. Report an issue: GitHub.

Appendix: source

Thrown at sources/presentation/Stride.Core.Presentation.Wpf/Extensions/DependencyObjectExtensions.cs:253

                return null;
            }
        }

        /// <summary>
        /// Find the first child that match the given type.
        /// </summary>
        /// <typeparam name="T">Type of child to find.</typeparam>
        /// <param name="source">Base node from where to start looking for child.</param>
        /// <param name="getChildrenCountFunc">Function that provide the number of children in the current element.</param>
        /// <param name="getChildFunc">Function that provide a given child element by its index.</param>
        /// <returns>Returns the retrieved child, or null otherwise.</returns>
        [CanBeNull]
        private static T FindChildOfType<T>([NotNull] DependencyObject source, [NotNull] Func<DependencyObject, int> getChildrenCountFunc,
            [NotNull] Func<DependencyObject, int, DependencyObject> getChildFunc) where T : DependencyObject
        {
            if (source == null) throw new ArgumentNullException(nameof(source));
            if (getChildrenCountFunc == null) throw new ArgumentNullException(nameof(getChildrenCountFunc));
            if (getChildFunc == null) throw new ArgumentNullException(nameof(getChildFunc));

            var childCount = getChildrenCountFunc(source);
            for (var i = 0; i < childCount; i++)
            {
                var child = getChildFunc(source, i);
                if (child != null)
                {
                    if (child is T)
                        return child as T;
                    child = FindChildOfType<T>(child, getChildrenCountFunc, getChildFunc);
                    if (child != null)
                        return (T)child;
                }
            }
            return null;
        }

        /// <summary>

View on GitHub (pinned to 96fad776d2)