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

  1. Filter nulls out of the list before passing it: `ids.Where(x => x.HasValue).Select(x => x.Value)`.
  2. Ensure the first element specifically is non-null (reorder or remove the leading null).
  3. Provide an explicit type by using a DbString/typed list so Dapper does not need to infer from the first item.
  4. 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

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


AI-assisted analysis of DapperLib/Dapper@72a54c475f (2026-08-13). Data as JSON: /api/errors/f82d9bf96651d73f. Report an issue: GitHub.