dotnet/BenchmarkDotNet · error · NotSupportedException

AsyncMethodBuilderAttribute not found on type {asyncType.Get

Error message

AsyncMethodBuilderAttribute not found on type {asyncType.GetDisplayName()} from {Descriptor.DisplayInfo}

What it means

The InProcess async emitter locates the async method builder via AsyncMethodBuilderAttribute on the returned awaitable type; the attribute is missing on the type used by the benchmark.

Source

Thrown at src/BenchmarkDotNet/Toolchains/InProcess/Emit/Implementation/Emitters/AsyncCoreEmitterBase.cs:133

            return typeof(AsyncTaskMethodBuilder);

            Type GetBuilderTypeFromUserSpecifiedAsyncType(Type asyncType)
            {
                if (asyncType.GetAsyncMethodBuilderAttribute() is { } typeAttr
                    && typeAttr.GetType().GetProperty(nameof(AsyncMethodBuilderAttribute.BuilderType), BindingFlags.Public | BindingFlags.Instance)?.GetValue(typeAttr) is Type typeBuilderType)
                {
                    return GetConcreteBuilderType(typeBuilderType, asyncType);
                }
                // Task and Task<T> are not annotated with their builder type, the C# compiler special-cases them.
                if (asyncType == typeof(Task))
                {
                    return typeof(AsyncTaskMethodBuilder);
                }
                if (asyncType.IsGenericType && asyncType.GetGenericTypeDefinition() == typeof(Task<>))
                {
                    return typeof(AsyncTaskMethodBuilder<>).MakeGenericType([asyncType.GetGenericArguments()[0]]);
                }
                throw new NotSupportedException($"AsyncMethodBuilderAttribute not found on type {asyncType.GetDisplayName()} from {Descriptor.DisplayInfo}");
            }

            static Type GetConcreteBuilderType(Type builderType, Type forReturnType)
            {
                if (!builderType.IsGenericTypeDefinition)
                {
                    return builderType;
                }
                if (builderType.GetGenericArguments().Length != 1)
                {
                    throw new NotSupportedException($"AsyncMethodBuilder {builderType.GetDisplayName()} has generic arity greater than 1.");
                }
                var resultType = forReturnType
                    .GetMethod(nameof(Task.GetAwaiter), BindingFlags.Public | BindingFlags.Instance)!
                    .ReturnType
                    .GetMethod(nameof(TaskAwaiter.GetResult), BindingFlags.Public | BindingFlags.Instance)!
                    .ReturnType;
                return builderType.MakeGenericType([resultType]);

View on GitHub (pinned to b515068b61)

Solutions

  1. Make sure the workload returns a type annotated with AsyncMethodBuilderAttribute (Task, Task<T>, ValueTask, ValueTask<T>, or a custom task-like type that declares the attribute).
  2. Reference a framework version where the returned async type carries AsyncMethodBuilderAttribute.
  3. For custom task-like types, add [AsyncMethodBuilder(typeof(YourBuilder))] to the type.

When it happens

Trigger: Thrown at src/BenchmarkDotNet/Toolchains/InProcess/Emit/Implementation/Emitters/AsyncCoreEmitterBase.cs:133 when the library encounters an invalid state.

Common situations: See trigger scenarios.


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