dotnet/BenchmarkDotNet · error · ArgumentException

The methodToCall should have non-null DeclaringType.

Error message

The methodToCall should have non-null DeclaringType.

What it means

EmitInstanceCallThisValueOnStack (internal) requires the target MethodInfo to have a non-null DeclaringType before it can emit an instance call. It throws ArgumentException when methodToCall.DeclaringType is null. This guards an internal precondition of the IL emitter.

Solutions

  1. Reduce the benchmark to a plain instance method on a normal class and retry.
  2. Upgrade BenchmarkDotNet to the latest release.
  3. Report the failing benchmark as a reproducible issue if it persists.
Defensive patterns

Strategy: try-catch

Try / catch

try { runner.Run(); }
catch (ArgumentException ex) when (ex.Message.Contains("non-null DeclaringType")) { /* simplify benchmark, report issue */ }

Prevention

When it happens

Trigger: The internal emitter receives a MethodInfo whose DeclaringType is null (e.g. a global method, a dynamically built method without a declaring type, or an unbound generic method), so it cannot emit a correct callvirt/call site.

Common situations: Edge cases in benchmark code generation involving dynamic or unbound methods; almost always a library codegen bug, not user config.

Related errors


AI-assisted analysis of dotnet/BenchmarkDotNet@b515068b61 (2026-08-13). Data as JSON: /api/errors/e5f197dcd18074c8. Report an issue: GitHub.

Appendix: source

Thrown at src/BenchmarkDotNet/Helpers/Reflection.Emit/IlGeneratorCallExtensions.cs:34

            EmitCallCore(ilBuilder, null, methodToCall, argLocals);
        }

        public static void EmitInstanceCallThisValueOnStack(
            this ILGenerator ilBuilder,
            LocalBuilder optionalLocalThis,
            MethodInfo methodToCall,
            params LocalBuilder[] argLocals) =>
            EmitInstanceCallThisValueOnStack(ilBuilder, optionalLocalThis, methodToCall, argLocals, false);

        public static void EmitInstanceCallThisValueOnStack(
            this ILGenerator ilBuilder,
            LocalBuilder? optionalLocalThis,
            MethodInfo methodToCall,
            IEnumerable<LocalBuilder> argLocals,
            bool forceDirectCall = false)
        {
            if (methodToCall.DeclaringType == null)
                throw new ArgumentException($"The {nameof(methodToCall)} should have non-null {nameof(methodToCall.DeclaringType)}.");

            if (methodToCall.IsStatic)
                throw new ArgumentException($"Method {methodToCall} should be instance method.");

            /*
                IL_0005: stloc.s 11
                ...
                IL_0007: callvirt instance valuetype [mscorlib]System.Runtime.CompilerServices.TaskAwaiter`1<!0> class [mscorlib]System.Threading.Tasks.Task`1<int32>::GetAwaiter()
                --or-
                IL_000d: ldloca.s 11
                IL_000f: call instance !0 valuetype [mscorlib]System.Runtime.CompilerServices.TaskAwaiter`1<int32>::GetResult()
            */
            if (methodToCall.DeclaringType.IsValueType)
            {
                ArgumentNullException.ThrowIfNull(optionalLocalThis);

                ilBuilder.EmitStloc(optionalLocalThis);
                EmitCallCore(ilBuilder, optionalLocalThis, methodToCall, argLocals, forceDirectCall);

View on GitHub (pinned to b515068b61)