dotnet/BenchmarkDotNet · error · InvalidOperationException
The argument must be an array
Error message
The argument must be an array
What it means
ArrayParam.FromObject is the reflection entry point used when a benchmark argument or [Params] value is supplied as a boxed object that BDN must render into source code. It requires the object to be an actual array (type.IsArray true). If the object is a List, IEnumerable, a scalar, or any other reference/collection type, IsArray is false and it throws InvalidOperationException.
Source
Thrown at src/BenchmarkDotNet/Code/ArrayParam.cs:72
/// <summary>
/// for types where calling .ToString() will be enough to re-create them in auto-generated source code file (integers, strings and other primitives)
/// </summary>
public static ArrayParam<T> ForPrimitives(T[] array) => new ArrayParam<T>(array);
/// <summary>
/// for types where calling .ToString() will be NOT enough to re-create them in auto-generated source code file
/// </summary>
/// <param name="array">the array</param>
/// <param name="toSourceCode">method which transforms an item of type T to it's C# representation
/// example: point => $"new Point2d({point.X}, {point.Y})"
/// </param>
[PublicAPI] public static ArrayParam<T> ForComplexTypes(T[] array, Func<T, string> toSourceCode) => new ArrayParam<T>(array, toSourceCode);
internal static IParam? FromObject(object array)
{
var type = array.GetType();
if (!type.IsArray)
throw new InvalidOperationException("The argument must be an array");
var elementType = type.GetElementType();
if (elementType == null)
throw new InvalidOperationException("Failed to determine type of array elements");
if (!SourceCodeHelper.IsCompilationTimeConstant(elementType))
throw new InvalidOperationException("The argument must be an array of primitives");
var arrayParamType = typeof(ArrayParam<>).MakeGenericType(elementType);
var methodInfo = arrayParamType.GetMethod(nameof(ForPrimitives), BindingFlags.Public | BindingFlags.Static)
?? throw new InvalidOperationException($"{nameof(ForPrimitives)} not found");
return (IParam?)methodInfo.Invoke(null, [array]);
}
}
}View on GitHub (pinned to b515068b61)
Solutions
- Convert the collection to an array before it reaches BDN: values.ToArray().
- For [ParamsSource], return an IReadOnlyList/array of the element type, not a List of arrays.
- Ensure [Arguments] array arguments are declared as actual T[] parameters.
- For complex element types, use ArrayParam<T>.ForComplexTypes(arr, toSourceCode) instead of FromObject.
Example fix
// before
public IEnumerable<object> Values() => new List<object> { 1, 2, 3 };
[ParamsSource(nameof(Values))] public int N;
// after
public IEnumerable<int> Values() => new[] { 1, 2, 3 };
[ParamsSource(nameof(Values))] public int N; Defensive patterns
Strategy: type-guard
Validate before calling
if (array == null || !array.GetType().IsArray)
throw new ArgumentException("An array argument is required.", nameof(array));
return ArrayParam.FromObject(array); Type guard
static bool IsArrayParamCompatible(object? o) => o is not null && o.GetType().IsArray;
Try / catch
try { return ArrayParam.FromObject(obj); }
catch (InvalidOperationException ex) when (ex.Message.Contains("must be an array"))
{
// materialize to an array and retry, or reject the param source
} Prevention
- Return arrays (or element-typed IEnumerables) from [ParamsSource], not List<object> or object collections.
- Ensure [Arguments] array parameters are declared as T[].
- Convert collections with .ToArray() before they reach BDN.
When it happens
Trigger: Passing a non-array (List<T>, IEnumerable<T>, a single value, or a jagged/complex object) where BDN expects an array argument via [Arguments] / [ParamsSource] / global arguments that route through FromObject.
Common situations: Using [ParamsSource] that returns a List instead of an array, supplying a single object instead of an array, or a custom IParam implementation that calls FromObject on incompatible input.
Related errors
- Failed to determine type of array elements
- The argument must be an array of primitives
- Type {0}: no settable property {1} found.
- Please use Targets property
- Field 'ConsoleRunnerPackage' not found.
AI-assisted analysis of dotnet/BenchmarkDotNet@b515068b61 (2026-08-13).
Data as JSON: /api/errors/563693db9575a5e6.
Report an issue: GitHub.