dotnet/BenchmarkDotNet · error · ArgumentException

Extend a an Expression with a valid Body

Error message

Extend a an Expression with a valid Body

What it means

ReportExtensions.GetReportFor<T>(Summary, Expression<Action<T>>) requires a lambda expression tree whose Body is non-null. The exception fires when actionExp.Body == null, which is abnormal for a compiler-generated expression and usually indicates a malformed or default-valued expression was passed.

Source

Thrown at src/BenchmarkDotNet/Extensions/ReportExtensions.cs:12

using BenchmarkDotNet.Mathematics;
using BenchmarkDotNet.Reports;
using System.Linq.Expressions;

namespace BenchmarkDotNet.Extensions
{
    public static class ReportExtensions
    {
        public static BenchmarkReport GetReportFor<T>(this Summary summary, Expression<Action<T>> actionExp)
        {
            if (actionExp.Body == null)
                throw new ArgumentException("Extend a an Expression with a valid Body", nameof(actionExp));

            if (!(actionExp.Body is MethodCallExpression methodExp))
                throw new ArgumentException("Extend a MethodCallExpression, but got a " + actionExp.Body.GetType().Name, nameof(actionExp));

            return summary.Reports.First(r => r.BenchmarkCase.Descriptor.WorkloadMethod == methodExp.Method);
        }

        public static IList<Measurement> GetRunsFor<T>(this Summary summary, Expression<Action<T>> actionExp)
        {
            return summary.GetReportFor(actionExp).GetResultRuns().ToList();
        }

        public static Statistics GetStatistics(this IReadOnlyCollection<Measurement> runs)
        {
            if (runs.IsEmpty())
                throw new InvalidOperationException("List of measurements contains no elements");
            return new Statistics(runs.Select(r => r.GetAverageTime().Nanoseconds));
        }

View on GitHub (pinned to b515068b61)

Solutions

  1. Pass a normal lambda that calls a benchmark method, e.g. summary.GetReportFor(b => b.MyBenchmark()).
  2. If constructing the expression programmatically, ensure the lambda's Body is a real Expression node before passing it in.
  3. Guard with a null check on actionExp.Body before calling GetReportFor.

Example fix

// before
var report = summary.GetReportFor(default(Expression<Action<MyBench>>));

// after
var report = summary.GetReportFor(b => b.Run());
Defensive patterns

Strategy: validation

Validate before calling

Expression<Action<T>> expr = b => b.Run();
if (expr?.Body == null) throw new InvalidOperationException("expression must have a body");
var report = summary.GetReportFor(expr);

Prevention

When it happens

Trigger: Calling summary.GetReportFor(x => ...) with a manually constructed or default(Expression<Action<T>>) whose Body is null, or an expression tree built via the Expression API that was never assigned a Body.

Common situations: Passing default(Expression<Action<T>>) by mistake, building expression trees by hand incorrectly, or a deserialization/reflection scenario producing a degenerate Expression.

Related errors


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