stride3d/stride · error · ArgumentNullException

Value cannot be null. (Parameter 'ownerType')

Error message

Value cannot be null. (Parameter 'ownerType')

What it means

DependencyPropertyFactory.Register requires an owner Type for every dependency property; a null ownerType makes it impossible to scope the registered property key. The factory validates arguments up front and throws ArgumentNullException(nameof(ownerType)).

Solutions

  1. Pass the concrete owner type, e.g. typeof(MyControl), as the ownerType argument
  2. If the type is resolved dynamically, check it for null before calling Register
  3. Move registration into the owner class's static constructor so the type is certainly available

Example fix

// before
var key = DependencyPropertyFactory.Register("MyProp", null, 0, null, null); // throws
// after
var key = DependencyPropertyFactory.Register("MyProp", typeof(MyControl), 0, null, null);
Defensive patterns

Strategy: validation

Validate before calling

if (name == null || ownerType == null)
    throw new ArgumentException("name and ownerType are required before Register");

Type guard

bool CanRegister(string name, Type ownerType) => !string.IsNullOrEmpty(name) && ownerType != null;

Try / catch

try
{
    key = DependencyPropertyFactory.Register(name, ownerType, defaultValue, null, null);
}
catch (ArgumentNullException ex)
{
    // log which argument was null; fix the registration site
}

Prevention

When it happens

Trigger: Calling DependencyPropertyFactory.Register<T>(name, null, defaultValue, ...) with an uninitialized or generic-resolved owner type; a static field initializer running before the owner type constant is set; reflection-based registration where the owner type lookup returned null.

Common situations: Refactoring control classes and leaving a TypeOf/typeof expression null; dynamic plugin registration where the type is resolved from config; code generation output with a missing owner type argument.

Related errors


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

Appendix: source

Thrown at sources/engine/Stride.UI/DependencyPropertyFactory.cs:71

        {
            return Register(name, ownerType, defaultValue, null, invalidationCallback);
        }

        /// <summary>
        /// Registers a dependency property.
        /// </summary>
        /// <typeparam name="T">The type of the property.</typeparam>
        /// <param name="name">The name of the property.</param>
        /// <param name="ownerType">The type that is registering the property.</param>
        /// <param name="defaultValue">The default value of the property.</param>
        /// <param name="validateValueCallback">A callback for validation/coercision of the property's value.</param>
        /// <param name="invalidationCallback">A callback to invalidate an object state after a modification of the property's value.</param>
        /// <param name="metadatas">The metadatas.</param>
        /// <returns></returns>
        public static PropertyKey<T> Register<T>(string name, Type ownerType, T defaultValue, ValidateValueCallback<T> validateValueCallback, ObjectInvalidationCallback<T> invalidationCallback, params PropertyKeyMetadata[] metadatas)
        {
            if (name == null) throw new ArgumentNullException(nameof(name));
            if (ownerType == null) throw new ArgumentNullException(nameof(ownerType));
            if (metadatas == null) throw new ArgumentNullException(nameof(metadatas));

            return RegisterCommon(DependencyPropertyKeyMetadata.Default, name, ownerType, defaultValue, validateValueCallback, invalidationCallback, metadatas);
        }

        /// <summary>
        /// Registers an attached dependency property.
        /// </summary>
        /// <typeparam name="T">The type of the property.</typeparam>
        /// <param name="name">The name of the property.</param>
        /// <param name="ownerType">The type that is registering the property.</param>
        /// <param name="defaultValue">The default value of the property.</param>
        /// <returns></returns>
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static PropertyKey<T> RegisterAttached<T>(string name, Type ownerType, T defaultValue)
        {
            return RegisterAttached(name, ownerType, defaultValue, null, null);
        }

View on GitHub (pinned to 96fad776d2)