dotnet/orleans · error · ArgumentNullException
Value cannot be null. (Parameter 'query')
Error message
Value cannot be null. (Parameter 'query')
What it means
Thrown by RelationalStorage.ReadAsync<TResult>(string query, ...) when query is null. The method deliberately allows empty strings (the database will surface its own error) but rejects null outright with ArgumentNullException(nameof(query)). The selector, not the query text, is the only other hard prerequisite.
Source
Thrown at src/AdoNet/Shared/Storage/RelationalStorage.cs:197
/// //marked with by convention by underscore (_).
/// }, (selector, resultSetCount) =>
/// {
/// //This function is called once for each row returned, so the final result will be an
/// //IEnumerable<Information>.
/// return new Information
/// {
/// TABLE_CATALOG = selector.GetValueOrDefault<string>("TABLE_CATALOG"),
/// TABLE_NAME = selector.GetValueOrDefault<string>("TABLE_NAME")
/// }
///}).ConfigureAwait(continueOnCapturedContext: false);
/// </code>
/// </example>
public async Task<IEnumerable<TResult>> ReadAsync<TResult>(string query, Action<IDbCommand>? parameterProvider, Func<IDataRecord, int, CancellationToken, Task<TResult>> selector, CommandBehavior commandBehavior = CommandBehavior.Default, CancellationToken cancellationToken = default)
{
//If the query is something else that is not acceptable (e.g. an empty string), there will an appropriate database exception.
if (query == null)
{
throw new ArgumentNullException(nameof(query));
}
if (selector == null)
{
throw new ArgumentNullException(nameof(selector));
}
return (await ExecuteAsync(query, parameterProvider, ExecuteReaderAsync, selector, commandBehavior, cancellationToken).ConfigureAwait(false)).Item1;
}
/// <summary>
/// Executes a given statement. Especially intended to use with <em>INSERT</em>, <em>UPDATE</em>, <em>DELETE</em> or <em>DDL</em> queries.
/// </summary>
/// <param name="query">The query to execute.</param>
/// <param name="parameterProvider">Adds parameters to the query. Parameter names must match those defined in the query.</param>
/// <param name="commandBehavior">The command behavior that should be used. Defaults to <see cref="CommandBehavior.Default"/>.</param>
/// <param name="cancellationToken">The cancellation token. Defaults to <see cref="CancellationToken.None"/>.</param>View on GitHub (pinned to fca799fa70)
Solutions
- Pass a non-null SQL string; build queries with a builder that never returns null (use string.Empty to let the DB reject it, or validate first).
- Load SQL scripts defensively: var sql = await File.ReadAllTextAsync(path); and check for null/empty before calling ReadAsync.
- Coalesce nulls: query ?? throw new ArgumentNullException(nameof(query)).
- Unit-test query providers to guarantee non-null output.
Example fix
// before
var rows = await storage.ReadAsync<T>(queryOrNull, p, selector);
// after
if (queryOrNull is null) throw new InvalidOperationException("Query not loaded.");
var rows = await storage.ReadAsync<T>(queryOrNull, p, selector); Defensive patterns
Strategy: validation
Validate before calling
if (query is null) throw new ArgumentNullException(nameof(query));
Type guard
static bool HasQuery(string? q) => q is not null;
Try / catch
try { await storage.ReadAsync<T>(query, p, selector); }
catch (ArgumentNullException ex) when (ex.ParamName == nameof(query)) { /* load script */ } Prevention
- Load SQL scripts at startup and assert non-null.
- Enable nullable reference types so null queries are compile-time warnings.
- Use a query-builder that never returns null.
When it happens
Trigger: Calling storage.ReadAsync<TResult>(null, parameterProvider, selector, ...) where the query string was not supplied, e.g. a query-builder returned null or a field was not loaded from a script file.
Common situations: See trigger scenarios.
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 'selector')
AI-assisted analysis of dotnet/orleans@fca799fa70 (2026-08-13).
Data as JSON: /api/errors/77f99ba24dd24fbf.
Report an issue: GitHub.