stride3d/stride · error · ArgumentNullException

Value cannot be null. (Parameter 'getChildrenCountFunc')

Error message

Value cannot be null. (Parameter 'getChildrenCountFunc')

What it means

FindChildOfType<T> is a private helper in Stride's Wpf presentation library that walks a visual/logical tree using caller-supplied delegate functions. It validates all arguments up front and throws ArgumentNullException when the getChildrenCountFunc delegate is null, because the recursion cannot enumerate children without it.

Solutions

  1. Pass a non-null count delegate, e.g. VisualTreeHelper.GetChildrenCount, when calling FindChildOfType.
  2. Check argument order in the call — the count func is the 2nd parameter after source.
  3. If the delegate is computed at runtime, throw or substitute a default (d => 0) instead of passing null.
  4. Null-check the delegate at the call site before invoking the helper.

Example fix

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

Strategy: validation

Validate before calling

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

Type guard

static bool CanFindChild<T>(DependencyObject src, Func<DependencyObject,int> count, Func<DependencyObject,int,DependencyObject> get) where T : DependencyObject => src != null && count != null && get != null;

Try / catch

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

Prevention

When it happens

Trigger: Calling FindChildOfType (or its public wrappers FindVisualChildOfType/FindLogicalChildOfType-style overloads) with a null children-count selector delegate while source and getChildFunc are valid.

Common situations: Constructing the delegates dynamically (e.g. from a reflected or conditional expression) so one branch yields null; refactoring call sites where the count delegate was removed but still passed; copy-pasting an overload call with wrong argument order.

Related errors


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

Appendix: source

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

                // failed to find visual parent
                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;
        }

View on GitHub (pinned to 96fad776d2)