dotnet/orleans · error · ArgumentNullException
Value cannot be null. (Parameter 'parameters')
Error message
Value cannot be null. (Parameter 'parameters')
What it means
Thrown by RelationalStorageExtensions.ExecuteMultipleInsertIntoAsync<T> when the parameters enumerable is null. The method enumerates parameters to build the column list and value rows via reflection, so null is rejected with ArgumentNullException(nameof(parameters)). An empty enumerable is valid and yields a no-op insert.
Source
Thrown at src/AdoNet/Shared/Storage/RelationalStorageExtensions.cs:62
/// <typeparam name="T"></typeparam>
/// <param name="storage">The storage to use.</param>
/// <param name="tableName">The table name to against which to execute the query.</param>
/// <param name="parameters">The parameters to insert.</param>
/// <param name="nameMap">If provided, maps property names from <typeparamref name="T"/> to ones provided in the map.</param>
/// <param name="onlyOnceColumns">If given, SQL parameter values for the given <typeparamref name="T"/> property types are generated only once. Effective only when <paramref name="useSqlParams"/> is <em>TRUE</em>.</param>
/// <param name="useSqlParams"><em>TRUE</em> if the query should be in parameterized form. <em>FALSE</em> otherwise.</param>
/// <param name="cancellationToken">The cancellation token. Defaults to <see cref="CancellationToken.None"/>.</param>
/// <returns>The rows affected.</returns>
public static Task<int> ExecuteMultipleInsertIntoAsync<T>(this IRelationalStorage storage, string tableName, IEnumerable<T> parameters, IReadOnlyDictionary<string, string>? nameMap = null, IEnumerable<string>? onlyOnceColumns = null, bool useSqlParams = true, CancellationToken cancellationToken = default)
{
if(string.IsNullOrWhiteSpace(tableName))
{
throw new ArgumentException("The name must be a legal SQL table name", nameof(tableName));
}
if(parameters == null)
{
throw new ArgumentNullException(nameof(parameters));
}
var storageConsts = DbConstantsStore.GetDbConstants(storage.InvariantName);
var startEscapeIndicator = storageConsts.StartEscapeIndicator;
var endEscapeIndicator = storageConsts.EndEscapeIndicator;
//SqlParameters map is needed in case the query needs to be parameterized in order to avoid two
//reflection passes as first a query needs to be constructed and after that when a database
//command object has been created, parameters need to be provided to them.
var sqlParameters = new Dictionary<string, object?>();
const string insertIntoValuesTemplate = "INSERT INTO {0} ({1}) SELECT {2};";
var columns = string.Empty;
var values = new List<string>();
if(parameters.Any())
{
//Type and property information are the same for all of the objects.
//The following assumes the property names will be retrieved in the sameView on GitHub (pinned to fca799fa70)
Solutions
- Pass an empty collection instead of null when there is nothing to insert: parameters ?? Array.Empty<T>().
- Initialize list fields and return Enumerable.Empty<T>() from helpers that may have no rows.
- Enable nullable reference types to surface null-typed arguments at compile time.
- Guard at the boundary: if (parameters is null) return Task.FromResult(0);
Example fix
// before await storage.ExecuteMultipleInsertIntoAsync(table, parameters: null); // after await storage.ExecuteMultipleInsertIntoAsync(table, parameters ?? Array.Empty<T>());
Defensive patterns
Strategy: validation
Validate before calling
var rows = parameters ?? Array.Empty<T>();
Type guard
static bool HasParameters<T>(IEnumerable<T>? p) => p is not null;
Try / catch
try { await storage.ExecuteMultipleInsertIntoAsync(table, rows); }
catch (ArgumentNullException ex) when (ex.ParamName == nameof(rows)) { /* pass empty */ } Prevention
- Return Enumerable.Empty<T>() from helpers that may have no rows.
- Coalesce nulls at the call site: parameters ?? Array.Empty<T>().
- Enable nullable reference types.
When it happens
Trigger: Calling ExecuteMultipleInsertIntoAsync with parameters: null, e.g. a caller passed an uninitialized list or a LINQ Where that was never assigned.
Common situations: Batching code that returns null instead of an empty list when there is nothing to insert; refactor that swapped an argument; null-coalescing missing at the call site.
Related errors
- Invalid offset length
- The name of invariant must contain characters
- Connection string must contain characters
- Configure exactly one of {nameof(connectionString)} or {name
- Value cannot be null. (Parameter 'query')
AI-assisted analysis of dotnet/orleans@fca799fa70 (2026-08-13).
Data as JSON: /api/errors/a041f7ec13d08678.
Report an issue: GitHub.