DapperLib/Dapper · error · InvalidOperationException
An enumerable sequence of parameters (arrays, lists, etc) is
Error message
An enumerable sequence of parameters (arrays, lists, etc) is not allowed in this context
What it means
Thrown by GetCacheInfo when the example parameter object is itself a multi-exec enumerable (an array, List<T>, etc. that is not a string, not an IDynamicParameters, and not an IEnumerable<KeyValuePair<string,object>>). GetCacheInfo builds a single-command parameter reader, so it cannot iterate a sequence; only the `Execute` path supports multi-exec. Passing a raw list where a single parameter object is expected is therefore rejected when the cache entry is first created.
Source
Thrown at Dapper/SqlMapper.cs:1860
for (var i = startIdx - 1; i > 0; --i)
{
if (string.Equals(splitOn, reader.GetName(i), StringComparison.OrdinalIgnoreCase))
{
return i;
}
}
throw MultiMapException(reader, splitOn);
}
private static CacheInfo GetCacheInfo(Identity identity, object? exampleParameters, bool addToCache)
{
if (!TryGetQueryCache(identity, out CacheInfo? info))
{
if (GetMultiExec(exampleParameters) is not null)
{
throw new InvalidOperationException("An enumerable sequence of parameters (arrays, lists, etc) is not allowed in this context");
}
info = new CacheInfo();
if (identity.ParametersType is not null)
{
Action<IDbCommand, object?> reader;
if (exampleParameters is IDynamicParameters)
{
reader = (cmd, obj) => ((IDynamicParameters)obj!).AddParameters(cmd, identity);
}
else if (exampleParameters is IEnumerable<KeyValuePair<string, object>>)
{
reader = (cmd, obj) =>
{
IDynamicParameters mapped = new DynamicParameters(obj!);
mapped.AddParameters(cmd, identity);
};
}
else
View on GitHub (pinned to 72a54c475f)
Solutions
- Wrap the sequence in an anonymous object: `Query<T>("... in @ids", new { ids = theList })` so Dapper does IN-expansion instead of multi-exec.
- If you genuinely want per-row execution, use `Execute(...)` (the only method that supports multi-exec).
- For querying multiple rows by a key list, use the `IN @ids` pattern with the list as a named member, not as `param` itself.
- If the object should be treated as a single parameter set, convert it to a concrete class or DynamicParameters before passing it.
Example fix
// before (throws: list is the top-level param)
var rows = cnn.Query<Foo>("select * from Foo where Id in @Ids", new[] { 1, 2, 3 });
// after
var rows = cnn.Query<Foo>("select * from Foo where Id in @Ids", new { Ids = new[] { 1, 2, 3 } }); Defensive patterns
Strategy: validation
Validate before calling
// Never pass a raw list/array as the top-level param to Query; wrap it.
var p = new { Ids = theList };
var rows = cnn.Query<Foo>("select * from Foo where Id in @Ids", p); Type guard
static bool IsMultiExecParam(object? param) => param is IEnumerable and not string and not IDynamicParameters and not IEnumerable<KeyValuePair<string,object>>;
Prevention
- Wrap sequences in an anonymous object ({ ids = list }) for IN-expansion.
- Reserve raw-list params for Execute only.
- Add a code-review check: any Query(param) whose argument is IEnumerable should be wrapped.
When it happens
Trigger: Passing a list/array (e.g. `new[] { new {Id=1}, new {Id=2} }`) as the `param` argument to any query method OTHER than Execute/ExecuteAsync — for example `Query<T>(sql, myList)`, `QueryFirst`, `QuerySingle`, `QueryScalar`, or a multi-map Query. GetMultiExec (SqlMapper.cs:623) detects the enumerable, and because these paths do not loop over it, GetCacheInfo throws.
Common situations: Assuming `Query<T>('select * from t where id in @ids', theIdsList)` works the same as `Execute` (it does not — `IN` expansion needs the list nested in a parameter object, not as the top-level param); reusing an `Execute`-style batch array with a `Query` call; passing `IEnumerable<T>` of DTOs to a select.
Related errors
- MultiExec is not supported by ExecuteReader
- The member {name} of type {type.FullName} cannot be used as
- you must provide at least one type to deserialize
- When passing parameters by position, each parameter can only
- The first item in a list-expansion cannot be null
AI-assisted analysis of DapperLib/Dapper@72a54c475f (2026-08-13).
Data as JSON: /api/errors/6dbe2f7b0e1035cd.
Report an issue: GitHub.