AvaloniaUI/Avalonia · error · ArgumentException

Unexpected null returned from Type.GetTypeFromHandle in…

Error message

Unexpected null returned from Type.GetTypeFromHandle in MethodAsDelegateElement

What it means

Thrown as ArgumentException by the MethodAsDelegateElement constructor when Type.GetTypeFromHandle(delegateType) returns null. A RuntimeTypeHandle must correspond to a loaded Type; a null result means the handle is invalid, zero, or refers to a type in an unloaded assembly.

Solutions

  1. Obtain the RuntimeTypeHandle from a live loaded Type via typeof(T).TypeHandle or type.TypeHandle, never default.
  2. In trimming/AOT scenarios, ensure the delegate type is rooted/preserved so its handle resolves at runtime.
  3. Validate Type.GetTypeFromHandle(delegateType) != null before passing to the builder.

Example fix

// before
builder.Method(methodHandle, default(RuntimeTypeHandle)); // throws
// after
builder.Method(methodHandle, typeof(Action<string>).TypeHandle);
Defensive patterns

Strategy: validation

Validate before calling

var type = Type.GetTypeFromHandle(delegateType);
if (type is null)
    throw new ArgumentException("Invalid type handle", nameof(delegateType));
builder.Method(handle, delegateType);

Type guard

static bool IsValidTypeHandle(RuntimeTypeHandle h) =>
    Type.GetTypeFromHandle(h) is not null;

Try / catch

try { builder.Method(handle, delegateType); }
catch (ArgumentException ex) when (ex.Message.Contains("GetTypeFromHandle"))
{ /* obtain delegateType from typeof(T).TypeHandle; ensure assembly loaded */ }

Prevention

When it happens

Trigger: Constructing MethodAsDelegateElement with a default/uninitialized RuntimeTypeHandle, a handle to a type in an assembly that was unloaded, or a handle captured incorrectly. CompiledBindingPathBuilder.Method(handle, delegateType) forwards delegateType here.

Common situations: Passing default(RuntimeTypeHandle) instead of typeof(MyDelegate).TypeHandle. Type lives in an assembly not yet loaded or trimmed away (AOT/trimming). Reflection-based capture of a type handle before the assembly is resolved.

Related errors


AI-assisted analysis of AvaloniaUI/Avalonia@11c5427268 (2026-08-13). Data as JSON: /api/errors/f6b868bcc41235ef. Report an issue: GitHub.

Appendix: source

Thrown at src/Avalonia.Base/Data/CompiledBindingPath.cs:277

        public Func<WeakReference<object?>, IPropertyInfo, IPropertyAccessor> AccessorFactory { get; }

        public bool AcceptsNull { get; }

        public override string ToString()
            => _isFirstElement ? Property.Name : $".{Property.Name}";
    }

    internal class MethodAsDelegateElement : ICompiledBindingPathElement
    {
        public MethodAsDelegateElement(
            RuntimeMethodHandle method,
            RuntimeTypeHandle delegateType,
            bool acceptsNull)
        {
            Method = MethodBase.GetMethodFromHandle(method) as MethodInfo
                ?? throw new ArgumentException("Invalid method handle", nameof(method));
            DelegateType = Type.GetTypeFromHandle(delegateType)
                ?? throw new ArgumentException("Unexpected null returned from Type.GetTypeFromHandle in MethodAsDelegateElement");
            AcceptsNull = acceptsNull;
        }

        public MethodInfo Method { get; }

        public Type DelegateType { get; }

        public bool AcceptsNull { get; }
    }

    internal class MethodAsCommandElement : ICompiledBindingPathElement
    {
        public MethodAsCommandElement(string methodName, Action<object, object?> executeHelper, Func<object, object?, bool>? canExecuteHelper, string[] dependsOnElements)
        {
            MethodName = methodName;
            ExecuteMethod = executeHelper;
            CanExecuteMethod = canExecuteHelper;
            DependsOnProperties = new HashSet<string>(dependsOnElements);

View on GitHub (pinned to 11c5427268)