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
- Increase the number of operations per invocation using [OperationsPerInvoke(N)] to ensure measurable operation counts.
- Update BenchmarkDotNet to the latest version, as zero-operation detection bugs are often fixed in releases.
- Check the benchmark report logs for host-process errors or warnings that may indicate why operations were not counted.
- 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
- Use [OperationsPerInvoke(N)] for very fast benchmark methods to ensure measurable operation counts.
- Keep BenchmarkDotNet updated — zero-operation detection and measurement bugs are fixed over time.
- Check benchmark logs for host-process errors or JIT issues that could cause silent failures.
- If benchmarking trivial operations, loop the operation inside the benchmark method body.
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
- The '{variable.Key}' environment variables is defined twice
- Benchmark {benchmark.Name} has invalid number of arguments p
- Benchmark {benchmark.Name} has invalid number of defined arg
- Runtime not supported
AI-assisted analysis of dotnet/BenchmarkDotNet@b515068b61 (2026-08-13).
Data as JSON: /api/errors/8be8d030755db3a6.
Report an issue: GitHub.