dotnet/BenchmarkDotNet · error · InvalidOperationException
Failed to determine type of array elements
Error message
Failed to determine type of array elements
What it means
Inside ArrayParam.FromObject, after the IsArray check passes, type.GetElementType() is expected to yield the element type. For genuine CLR arrays this is essentially always non-null, so this throw is a defensive guard against exotic or edge-case array-like types where GetElementType returns null (e.g. certain Array-derived types or by-ref-like constructs produced via reflection).
Source
Thrown at src/BenchmarkDotNet/Code/ArrayParam.cs:75
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
- Use a concrete, standard array type (int[], string[], etc.) instead of an Array subclass or reflected construct.
- If you control the value, materialize it as a normal T[] before passing it in.
- Report it as a BDN issue if a plain array still triggers it, including the exact runtime/Type involved.
Example fix
// before
var arg = Array.CreateInstance(typeof(int), lengths, lowerBounds); // non-zero-based Array subclass
// after
var arg = new int[] { 1, 2, 3 }; // standard zero-based array Defensive patterns
Strategy: type-guard
Validate before calling
var t = array.GetType();
if (!t.IsArray || t.GetElementType() is null)
throw new ArgumentException("A standard zero-based array is required.", nameof(array));
return ArrayParam.FromObject(array); Type guard
static bool IsStandardArray(object? o) => o is not null && o.GetType().IsArray && o.GetType().GetElementType() is not null;
Try / catch
try { return ArrayParam.FromObject(obj); }
catch (InvalidOperationException ex) when (ex.Message.Contains("Failed to determine type"))
{
// copy into a concrete T[] and retry
} Prevention
- Use concrete zero-based arrays (int[], string[]) instead of Array.CreateInstance with bounds or Array subclasses.
- Materialize reflected/constructed arrays into standard T[] before passing to BDN.
When it happens
Trigger: Passing a Type whose IsArray is true but whose GetElementType() returns null, which can occur with non-standard Array subclasses or some reflected/constructed array types; not reachable with ordinary T[] values.
Common situations: Custom IParam providers or reflection-based argument plumbing that construct unusual array types, or runtime/CLR edge cases on uncommon targets.
Related errors
- The argument must be an array
- The argument must be an array of primitives
- Please use Targets property
- Field 'ConsoleRunnerPackage' not found.
- Unable to get value of 'ConsoleRunnerPackage'.
AI-assisted analysis of dotnet/BenchmarkDotNet@b515068b61 (2026-08-13).
Data as JSON: /api/errors/fa7fdd794a1fa711.
Report an issue: GitHub.