dotnet/BenchmarkDotNet · error · InvalidOperationException
Benchmark {benchmark.Name} has invalid number of arguments p
Error message
Benchmark {benchmark.Name} has invalid number of arguments provided by [ArgumentsSource({valuesInfo.source.Name})]! {array.Length} instead of {parameterDefinitions.Length}. What it means
Thrown by SmartParamBuilder.CreateForArguments when a benchmark method with multiple parameters is fed an object[] from [ArgumentsSource] whose element count does not match the benchmark's parameter count. The check `parameterDefinitions.Length != array.Length` fires inside the branch where the benchmark has more than one parameter and the yielded array does not align.
Source
Thrown at src/BenchmarkDotNet/Parameters/SmartParamBuilder.cs:45
internal static ParameterInstances CreateForArguments(MethodInfo benchmark, ParameterDefinition[] parameterDefinitions, (MemberInfo source, object[] values) valuesInfo, int sourceIndex, SummaryStyle summaryStyle)
{
var unwrappedValue = valuesInfo.values[sourceIndex];
if (unwrappedValue is object[] array)
{
Type? firstParamType = benchmark.GetParameters().FirstOrDefault()?.ParameterType;
// the user provided object[] for a benchmark accepting a single argument
if (parameterDefinitions.Length == 1 && array.Length == 1
&& (array[0]?.GetType() == firstParamType || (firstParamType != null && firstParamType.IsStackOnlyWithImplicitCast(array[0])))) // the benchmark that accepts an object[] as argument
{
return new ParameterInstances(
[Create(parameterDefinitions, array[0], valuesInfo.source, sourceIndex, argumentIndex: 0, summaryStyle)]);
}
if (parameterDefinitions.Length > 1)
{
if (parameterDefinitions.Length != array.Length)
throw new InvalidOperationException($"Benchmark {benchmark.Name} has invalid number of arguments provided by [ArgumentsSource({valuesInfo.source.Name})]! {array.Length} instead of {parameterDefinitions.Length}.");
return new ParameterInstances(
array.Select((value, argumentIndex) => Create(parameterDefinitions, value, valuesInfo.source, sourceIndex, argumentIndex, summaryStyle)).ToArray());
}
}
if (parameterDefinitions.Length == 1)
{
return new ParameterInstances([Create(parameterDefinitions, unwrappedValue, valuesInfo.source, sourceIndex, argumentIndex: 0, summaryStyle)]);
}
throw new NotSupportedException($"Benchmark {benchmark.Name} has invalid type of arguments provided by [ArgumentsSource({valuesInfo.source.Name})]. It should be IEnumerable<object[]> or IEnumerable<object>.");
}
private static ParameterInstance Create(ParameterDefinition[] parameterDefinitions, object value, MemberInfo source, int sourceIndex, int argumentIndex, SummaryStyle summaryStyle)
{
if (SourceCodeHelper.IsCompilationTimeConstant(value))
return new ParameterInstance(parameterDefinitions[argumentIndex], value, summaryStyle);View on GitHub (pinned to b515068b61)
Solutions
- Count the benchmark method parameters and ensure every object[] yielded by the source has exactly that length.
- Use a helper that constructs each row from named fields to avoid manual array sizing.
- If a single object[] argument is intended (benchmark takes object[] as one parameter), ensure only one parameter is declared and the source yields single-element arrays or scalar objects.
Example fix
// before
public IEnumerable<object[]> Data() => new[]
{
new object[] { 1, 2 }, // method has 3 params!
};
[Benchmark]
[ArgumentsSource(nameof(Data))]
public void Run(int a, int b, int c) { }
// after
public IEnumerable<object[]> Data() => new[]
{
new object[] { 1, 2, 3 },
}; Defensive patterns
Strategy: validation
Validate before calling
// Verify each ArgumentsSource row matches the benchmark parameter count
int paramCount = typeof(MyBench).GetMethod(nameof(MyBench.Run))!.GetParameters().Length;
foreach (var row in Data())
if (row.Length != paramCount)
throw new InvalidOperationException($"Row has {row.Length} elements, expected {paramCount}"); Prevention
- Write a unit test that asserts every row from the ArgumentsSource matches the method parameter count.
- Keep parameter definitions and data sources near each other in the class.
- When adding/removing a parameter, grep for the source method and update all rows.
When it happens
Trigger: A benchmark method declared as void Run(int a, int b, int c) with [ArgumentsSource(nameof(Data))] where Data yields object[] arrays of length 2 or 4 instead of 3. Each yielded array must exactly match the parameter count when the method has >1 parameter.
Common situations: Adding or removing a parameter from a benchmark method signature but forgetting to update the ArgumentsSource data provider. Returning jagged arrays of inconsistent lengths. Misunderstanding that for multi-parameter benchmarks each yielded item must be an array matching the full signature.
Related errors
- Benchmark {benchmark.Name} has invalid number of defined arg
- Benchmark {benchmark.Name} has invalid type of arguments pro
- The '{variable.Key}' environment variables is defined twice
- {type.Name} is generic type definition, use BenchmarkSwitche
- {methodType} method {methodInfo.Name} has incorrect signatur
AI-assisted analysis of dotnet/BenchmarkDotNet@b515068b61 (2026-08-13).
Data as JSON: /api/errors/52c096ffba8a59df.
Report an issue: GitHub.