dotnet/BenchmarkDotNet · critical · InvalidOperationException

An iteration with 'Operations == 0' detected

Error message

An iteration with 'Operations == 0' detected

What it means

Thrown after a benchmark run completes when any measurement in the report has Operations == 0. Each measurement should record at least one operation; a zero-operation measurement indicates the benchmark loop never executed its body, producing invalid statistics (division by zero in ops/sec). The check `report.AllMeasurements.Any(m => m.Operations == 0)` catches this.

Source

Thrown at src/BenchmarkDotNet/Running/BenchmarkRunnerClean.cs:267

                    var benchmark = benchmarks[i];

                    powerManagementApplier.ApplyPerformancePlan(benchmark.Job.Environment.PowerPlanMode
                        ?? benchmark.Job.ResolveValue(EnvironmentMode.PowerPlanModeCharacteristic, EnvironmentResolver.Instance).GetValueOrDefault());

                    var info = buildResults[benchmark];
                    var buildResult = info.buildResult;

                    if (buildResult.IsBuildSuccess)
                    {
                        if (!config.Options.IsSet(ConfigOptions.KeepBenchmarkFiles))
                            artifactsToCleanup.AddRange(buildResult.ArtifactsToCleanup);

                        eventProcessor.OnStartRunBenchmark(benchmark);
                        var report = await RunCore(benchmark, info.benchmarkId, logger, resolver, buildResult, benchmarkRunInfo.CompositeInProcessDiagnoser, cancellationToken).ConfigureAwait();
                        eventProcessor.OnEndRunBenchmark(benchmark, report);

                        if (report.AllMeasurements.Any(m => m.Operations == 0))
                            throw new InvalidOperationException("An iteration with 'Operations == 0' detected");
                        reports.Add(report);
                        if (report.GetResultRuns().Any())
                        {
                            var statistics = report.GetResultRuns().GetStatistics();
                            var formatter = statistics.CreateNanosecondFormatter(cultureInfo);
                            logger.WriteLineStatistic(statistics.ToString(cultureInfo, formatter));
                        }

                        if (!report.Success && config.Options.IsSet(ConfigOptions.StopOnFirstError))
                        {
                            stop = true;
                        }
                    }
                    else
                    {
                        reports.Add(new BenchmarkReport(false, benchmark, buildResult, buildResult, default, default));

                        if (buildResult.GenerateException != null)

View on GitHub (pinned to b515068b61)

Solutions

  1. Increase the number of operations per invocation using [OperationsPerInvoke(N)] to ensure measurable operation counts.
  2. Update BenchmarkDotNet to the latest version, as zero-operation detection bugs are often fixed in releases.
  3. Check the benchmark report logs for host-process errors or warnings that may indicate why operations were not counted.
  4. If benchmarking a trivial operation, wrap it in a loop inside the benchmark method body.

Example fix

// before
[Benchmark]
public void FastOp() { x += 1; }

// after
[Benchmark]
[OperationsPerInvoke(1000)]
public void FastOp()
{
    for (int i = 0; i < 1000; i++)
        x += 1;
}
Defensive patterns

Strategy: fallback

Try / catch

try
{
    var summary = BenchmarkRunner.Run<MyBench>(config);
}
catch (InvalidOperationException ex) when (ex.Message.Contains("Operations == 0"))
{
    // Retry with higher OperationsPerInvoke or adjust config
    config = config.AddJob(Job.Default.WithInvocationCount(1).WithUnrollFactor(16));
    var summary = BenchmarkRunner.Run<MyBench>(config);
}

Prevention

When it happens

Trigger: A benchmark method completes so quickly that the measurement engine fails to register operations, or a host-process issue causes the benchmark harness to return zero operations for one or more iterations. Can also indicate the generated host code crashed silently or the workload method was optimized away.

Common situations: Benchmarking extremely fast operations (sub-nanosecond) where the operation counter underflows. Using an older runtime or toolchain with measurement bugs. Process crashes or JIT issues in the host. Rare platform/timing edge cases.

Related errors


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