AvaloniaUI/Avalonia · error · ArgumentException

Invalid method handle

Error message

Invalid method handle

What it means

Thrown as ArgumentException (paramName 'method') by the MethodAsDelegateElement constructor when MethodBase.GetMethodFromHandle(method) returns null or a non-MethodInfo. A RuntimeMethodHandle must correspond to a valid managed method; if the handle is invalid, zero, or points to a non-method metadata token, resolution fails.

Source

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

        public IPropertyInfo Property { get; }

        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;

View on GitHub (pinned to 11c5427268)

Solutions

  1. Ensure the RuntimeMethodHandle passed to Method() is obtained from a live, loaded MethodInfo (e.g., methodInfo.MethodHandle) and not default.
  2. In trimming/AOT scenarios, ensure the target method is preserved (DynamicallyAccessedMembers or root) so its handle resolves.
  3. Validate the handle resolves before passing: MethodBase.GetMethodFromHandle(handle) != null.

Example fix

// before
builder.Method(default(RuntimeMethodHandle), delegateType); // throws
// after
builder.Method(myMethodInfo.MethodHandle, delegateType);
Defensive patterns

Strategy: validation

Validate before calling

var methodInfo = MethodBase.GetMethodFromHandle(handle) as MethodInfo;
if (methodInfo is null)
    throw new ArgumentException("Invalid method handle", nameof(handle));
builder.Method(handle, delegateType);

Type guard

static bool IsValidMethodHandle(RuntimeMethodHandle h) =>
    MethodBase.GetMethodFromHandle(h) is MethodInfo;

Try / catch

try { builder.Method(handle, delegateType); }
catch (ArgumentException ex) when (ex.ParamName == "method")
{ /* re-acquire the handle from a live MethodInfo; check trimming roots */ }

Prevention

When it happens

Trigger: Constructing MethodAsDelegateElement with a default/uninitialized RuntimeMethodHandle, a handle obtained from a dynamic method whose metadata is gone, or a handle from an unloaded assembly. CompiledBindingPathBuilder.Method(handle, delegateType) forwards to this constructor.

Common situations: Source generator / compiled-binding pipeline passes a RuntimeMethodHandle for a method that was trimmed (AOT/trimming removed it), or a handle captured before the method was finalized. Passing default(RuntimeMethodHandle) by mistake. Assembly unload/reload invalidating a captured handle.

Related errors


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