dotnet/wpf · error · ArgumentException

SR.Format(SR.DTypeNotSupportForSystemType, systemType.Name)

Error message

SR.Format(SR.DTypeNotSupportForSystemType, systemType.Name)

What it means

DependencyObjectType.FromSystemType throws ArgumentException when the supplied System.Type does not derive from DependencyObject. DependencyObjectTypes can only be registered for types in the DependencyObject hierarchy; the message names the offending system type.

Solutions

  1. Make the type derive from DependencyObject (directly or via a base class) before registering
  2. Filter candidate types with typeof(DependencyObject).IsAssignableFrom(t) before calling FromSystemType
  3. If the type cannot be a DependencyObject, use it as a plain property value instead of registering a DType
  4. Skip interfaces/abstract non-DO types in registration loops

Example fix

// before
var dType = DependencyObjectType.FromSystemType(typeof(MyPlainClass)); // not a DO
// after
if (typeof(DependencyObject).IsAssignableFrom(typeof(MyControl))) {
    var dType = DependencyObjectType.FromSystemType(typeof(MyControl));
}
Defensive patterns

Strategy: validation

Validate before calling

if (!typeof(DependencyObject).IsAssignableFrom(systemType))
    throw new ArgumentException($"{systemType.Name} must derive from DependencyObject");
var dType = DependencyObjectType.FromSystemType(systemType);

Type guard

static bool CanRegisterDType(Type t) => typeof(DependencyObject).IsAssignableFrom(t);

Try / catch

try { var dType = DependencyObjectType.FromSystemType(t); }
catch (ArgumentException) when (!typeof(DependencyObject).IsAssignableFrom(t)) { SkipRegistration(t); }

Prevention

When it happens

Trigger: Calling DependencyObjectType.FromSystemType(typeof(SomePoco)) where SomePoco does not inherit (directly or transitively) from DependencyObject.

Common situations: Passing a plain CLR class or interface intended for the property system without making it a DependencyObject, refactoring a class off the DependencyObject base while keeping DType registration, reflection-driven registration loops hitting non-DO types.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


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

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/WindowsBase/System/Windows/DependencyObjectType.cs:42

    ///     </list>
    /// </remarks>
    public class DependencyObjectType
    {
        /// <summary>
        ///     Retrieve a DependencyObjectType that represents a given system (CLR) type
        /// </summary>
        /// <param name="systemType">The system (CLR) type to convert</param>
        /// <returns>
        ///     A DependencyObjectType that represents the system (CLR) type (will create
        ///     a new one if doesn't exist)
        /// </returns>
        public static DependencyObjectType FromSystemType(Type systemType)
        {
            ArgumentNullException.ThrowIfNull(systemType);

            if (!typeof(DependencyObject).IsAssignableFrom(systemType))
            {
                throw new ArgumentException(SR.Format(SR.DTypeNotSupportForSystemType, systemType.Name));
            }

            return FromSystemTypeInternal(systemType);
        }

        /// <summary>
        ///     Helper method for the public FromSystemType call but without
        ///     the expensive IsAssignableFrom parameter validation.
        /// </summary>
        internal static DependencyObjectType FromSystemTypeInternal(Type systemType)
        {
            Debug.Assert(systemType != null && typeof(DependencyObject).IsAssignableFrom(systemType), "Invalid systemType argument");

            DependencyObjectType retVal;

            lock(_lock)
            {
                // Recursive routine to (set up if necessary) and use the

View on GitHub (pinned to 81131a70a4)