DapperLib/Dapper · error · NotSupportedException
The first item in a list-expansion cannot be null
Error message
The first item in a list-expansion cannot be null
What it means
Thrown by PackListParameters during `IN @list` expansion when the FIRST element of the supplied sequence is null. Dapper inspects the first non-null item to infer the DbType for the generated parameters (it cannot reliably infer a type from null), so a null-first list is rejected with NotSupportedException. Nulls in later positions are handled, but the leading element must not be null.
Source
Thrown at Dapper/SqlMapper.cs:2197
var count = 0;
bool isString = value is IEnumerable<string>;
bool isDbString = value is IEnumerable<DbString>;
DbType? dbType = null;
int splitAt = SqlMapper.Settings.InListStringSplitCount;
bool viaSplit = splitAt >= 0
&& TryStringSplit(ref list, splitAt, namePrefix, command, byPosition);
if (list is not null && !viaSplit)
{
object? lastValue = null;
foreach (var item in list)
{
if (++count == 1) // first item: fetch some type info
{
if (item is null)
{
throw new NotSupportedException("The first item in a list-expansion cannot be null");
}
if (!isDbString)
{
dbType = LookupDbType(item.GetType(), "", true, out var handler);
}
}
var nextName = namePrefix + count.ToString();
if (isDbString && item is DbString str)
{
str.AddParameter(command, nextName);
}
else
{
var listParam = command.CreateParameter();
listParam.ParameterName = nextName;
if (isString)
{
listParam.Size = DbString.DefaultLength;
View on GitHub (pinned to 72a54c475f)
Solutions
- Filter nulls out of the list before passing it: `ids.Where(x => x.HasValue).Select(x => x.Value)`.
- Ensure the first element specifically is non-null (reorder or remove the leading null).
- Provide an explicit type by using a DbString/typed list so Dapper does not need to infer from the first item.
- If the whole list can be null/empty, branch to a query without the IN clause.
Example fix
// before
var ids = new int?[] { null, 1, 2 };
var rows = cnn.Query<Foo>("select * from Foo where Id in @Ids", new { Ids = ids });
// after
var ids = new int?[] { null, 1, 2 }.Where(x => x.HasValue).Select(x => x.Value).ToList();
var rows = cnn.Query<Foo>("select * from Foo where Id in @Ids", new { Ids = ids }); Defensive patterns
Strategy: validation
Validate before calling
// Remove nulls (especially a leading null) before IN-expansion.
var clean = theList?.Where(x => x is not null).ToList();
if (clean is null || clean.Count == 0) return Array.Empty<Foo>();
var rows = cnn.Query<Foo>("select * from Foo where Id in @Ids", new { Ids = clean }); Type guard
static bool FirstItemNotNull(IEnumerable? list) { if (list is null) return true; var e = list.GetEnumerator(); return !e.MoveNext() || e.Current is not null; } Prevention
- Filter nulls out of lists used for IN expansion.
- Guard empty lists and skip the IN clause entirely.
- Use a typed/DbString list so Dapper does not infer type from item 0.
When it happens
Trigger: Passing `new { ids = list }` where `list`'s first element is null, in a `where id in @ids` clause, on a provider whose FeatureSupport.Arrays is false (so Dapper does individual-parameter expansion rather than a TVP). Example: `new[] { null, 1, 2 }`.
Common situations: User-supplied filter lists where an empty/null placeholder was prepended; lists built from optional inputs where the first entry was never set; concatenating a null sentinel onto the front of an id list.
Related errors
- Member '{name}' is an {nameof(ICustomQueryParameter)} and ca
- The member {name} of type {type.FullName} cannot be used as
- An enumerable sequence of parameters (arrays, lists, etc) is
- When passing parameters by position, each parameter can only
- ValueTuple should not be used for parameters - the language-
AI-assisted analysis of DapperLib/Dapper@72a54c475f (2026-08-13).
Data as JSON: /api/errors/f82d9bf96651d73f.
Report an issue: GitHub.