dotnet/BenchmarkDotNet · error · InvalidOperationException

AwaitHelper.GetResult is not available for workload return t

Error message

AwaitHelper.GetResult is not available for workload return type {0}. ConsumeTasksSynchronously only supports (Value)Task(<T>).

What it means

SyncTaskCoreEmitter consumes awaitable results synchronously via AwaitHelper.GetResult, which is only implemented for (Value)Task and (Value)Task<T>; other awaitable return types are rejected.

Source

Thrown at src/BenchmarkDotNet/Toolchains/InProcess/Emit/Implementation/Emitters/SyncTaskCoreEmitter.cs:50

                };

        protected override void EmitExtraGlobalCleanup(ILGenerator ilBuilder, LocalBuilder? thisLocal) { }

        protected override void EmitCoreImpl()
        {
            EmitAction(OverheadActionUnrollMethodName, overheadImplementationMethod, jobUnrollFactor, isWorkload: false);
            EmitAction(OverheadActionNoUnrollMethodName, overheadImplementationMethod, 1, isWorkload: false);
            EmitAction(WorkloadActionUnrollMethodName, Descriptor.WorkloadMethod, jobUnrollFactor, isWorkload: true);
            EmitAction(WorkloadActionNoUnrollMethodName, Descriptor.WorkloadMethod, 1, isWorkload: true);
        }

        private MethodBuilder EmitAction(string methodName, MethodInfo methodToCall, int unrollFactor, bool isWorkload)
        {
            MethodInfo? getResultMethod = null;
            if (isWorkload)
            {
                getResultMethod = AwaitHelper.GetGetResultMethod(methodToCall.ReturnType)
                    ?? throw new InvalidOperationException(
                        $"AwaitHelper.GetResult is not available for workload return type {methodToCall.ReturnType.GetDisplayName()}. ConsumeTasksSynchronously only supports (Value)Task(<T>).");
            }

            var invokeCountArg = new EmitParameterInfo(0, InvokeCountParamName, typeof(long));
            var actionMethodBuilder = runnableBuilder
                .DefineNonVirtualInstanceMethod(
                    methodName,
                    MethodAttributes.Private,
                    EmitParameterInfo.CreateReturnParameter(typeof(ValueTask<ClockSpan>)),
                    [
                        invokeCountArg,
                        new EmitParameterInfo(1, ClockParamName, typeof(IClock))
                    ]
                )
                .SetAggressiveOptimizationImplementationFlag();
            invokeCountArg.SetMember(actionMethodBuilder);

            var ilBuilder = actionMethodBuilder.GetILGenerator();

View on GitHub (pinned to b515068b61)

Solutions

  1. Return Task, Task<T>, ValueTask, or ValueTask<T> from the benchmark when ConsumeTasksSynchronously is enabled.
  2. Disable ConsumeTasksSynchronously in the config and let BDN await the result asynchronously.
  3. For custom awaitables, use the default (out-of-process) toolchain.

When it happens

Trigger: Thrown at src/BenchmarkDotNet/Toolchains/InProcess/Emit/Implementation/Emitters/SyncTaskCoreEmitter.cs:50 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/7bae81037912ff13. Report an issue: GitHub.