{"record":{"id":"76e728dc46b21067","repo":"dotnet/BenchmarkDotNet","slug":"totaloperations-count-can-t-change-during-the-benc","errorCode":null,"errorMessage":"TotalOperations count can't change during the benchmark run! Invalid trace!","messagePattern":"TotalOperations count can't change during the benchmark run! Invalid trace!","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/BenchmarkDotNet.Diagnostics.Windows/Tracing/TraceLogParser.cs","lineNumber":112,"sourceCode":"        private readonly List<double> workloadTimestamps = new List<double>(20);\n        private long? totalOperationsPerIteration;\n\n        private readonly List<(double timeStamp, ulong instructionPointer, int profileSource)> samples = [];\n\n        public bool HasBenchmarkEvents => overheadTimestamps.Any() || workloadTimestamps.Any();\n\n        public void HandleIterationEvent(double timeStamp, IterationMode iterationMode, long totalOperations)\n        {\n            if (iterationMode == IterationMode.Overhead)\n            {\n                overheadTimestamps.Add(timeStamp);\n            }\n            else if (iterationMode == IterationMode.Workload)\n            {\n                if (!totalOperationsPerIteration.HasValue)\n                    totalOperationsPerIteration = totalOperations;\n                else if (totalOperationsPerIteration.Value != totalOperations)\n                    throw new InvalidOperationException($\"TotalOperations count can't change during the benchmark run! Invalid trace!\");\n\n                workloadTimestamps.Add(timeStamp);\n            }\n        }\n\n        public void HandleNewSample(double timeStamp, ulong instructionPointer, int profileSourceId)\n            => samples.Add((timeStamp, instructionPointer, profileSourceId));\n\n        public IEnumerable<Metric> CalculateMetrics(Dictionary<int, int> profileSourceIdToInterval, PreciseMachineCounter[] counters)\n        {\n            if (overheadTimestamps.Count % 2 != 0)\n                throw new InvalidOperationException(\"One overhead iteration stop event is missing, unable to calculate stats\");\n            if (workloadTimestamps.Count % 2 != 0)\n                throw new InvalidOperationException(\"One workload iteration stop event is missing, unable to calculate stats\");\n            if (!totalOperationsPerIteration.HasValue)\n                throw new InvalidOperationException(\"TotalOperations is missing, unable to calculate stats\");\n\n            var overheadIterations = CreateIterationData(overheadTimestamps);","sourceCodeStart":94,"sourceCodeEnd":130,"githubUrl":"https://github.com/dotnet/BenchmarkDotNet/blob/b515068b61ad1c9c9aa938b8ece4af1e7d6d85a3/src/BenchmarkDotNet.Diagnostics.Windows/Tracing/TraceLogParser.cs#L94-L130","documentation":"ProcessMetrics.HandleIterationEvent throws when two Workload iteration events in the same benchmark run report a different TotalOperations count. The PMC metric calculation requires the operations-per-iteration to be constant so per-counter values can be divided by a single denominator. A mismatch means the trace is internally inconsistent.","triggerScenarios":"The benchmark engine emitted WorkloadActualStart/Stop events whose TotalOperations field differs between iterations (non-deterministic OperationCount, the [Benchmark] method mutating a shared counter, or a corrupted/partial ETW trace).","commonSituations":"Marking a method with [OperationsPerInvoke] while the method itself changes the count it reports; sharing mutable state across invocations; capturing a trace over a noisy machine where events from two processes interleave and get attributed incorrectly.","solutions":["Ensure the benchmarked method and its [OperationsPerInvoke] are deterministic and do not mutate global state between invocations.","Re-run in isolation (no other heavy processes) to avoid ETW event interleaving across processes.","If the workload legitimately varies, report it as an inconsistency upstream instead of relying on the PMC diagnoser metrics."],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":"try { /* run with PMC diagnoser */ }\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"TotalOperations count can't change\"))\n{\n    log.Error($\"Non-deterministic operations-per-iteration detected. Make the [Benchmark] deterministic. {ex.Message}\");\n}","preventionTips":["Keep [Benchmark] methods and [OperationsPerInvoke] deterministic with no shared mutable state.","Run in isolation so ETW does not interleave events from multiple processes."],"tags":["benchmarkdotnet","windows","etw","pmc","tracing","determinism"],"backgroundTag":null,"analyzedSha":"b515068b61ad1c9c9aa938b8ece4af1e7d6d85a3","analyzedAt":"2026-08-13T19:12:24.196Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}