{"record":{"id":"6dbe2f7b0e1035cd","repo":"DapperLib/Dapper","slug":"an-enumerable-sequence-of-parameters-arrays-list","errorCode":null,"errorMessage":"An enumerable sequence of parameters (arrays, lists, etc) is not allowed in this context","messagePattern":"An enumerable sequence of parameters \\(arrays, lists, etc\\) is not allowed in this context","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"Dapper/SqlMapper.cs","lineNumber":1860,"sourceCode":"\r\n            for (var i = startIdx - 1; i > 0; --i)\r\n            {\r\n                if (string.Equals(splitOn, reader.GetName(i), StringComparison.OrdinalIgnoreCase))\r\n                {\r\n                    return i;\r\n                }\r\n            }\r\n\r\n            throw MultiMapException(reader, splitOn);\r\n        }\r\n\r\n        private static CacheInfo GetCacheInfo(Identity identity, object? exampleParameters, bool addToCache)\r\n        {\r\n            if (!TryGetQueryCache(identity, out CacheInfo? info))\r\n            {\r\n                if (GetMultiExec(exampleParameters) is not null)\r\n                {\r\n                    throw new InvalidOperationException(\"An enumerable sequence of parameters (arrays, lists, etc) is not allowed in this context\");\r\n                }\r\n                info = new CacheInfo();\r\n                if (identity.ParametersType is not null)\r\n                {\r\n                    Action<IDbCommand, object?> reader;\r\n                    if (exampleParameters is IDynamicParameters)\r\n                    {\r\n                        reader = (cmd, obj) => ((IDynamicParameters)obj!).AddParameters(cmd, identity);\r\n                    }\r\n                    else if (exampleParameters is IEnumerable<KeyValuePair<string, object>>)\r\n                    {\r\n                        reader = (cmd, obj) =>\r\n                        {\r\n                            IDynamicParameters mapped = new DynamicParameters(obj!);\r\n                            mapped.AddParameters(cmd, identity);\r\n                        };\r\n                    }\r\n                    else\r","sourceCodeStart":1842,"sourceCodeEnd":1878,"githubUrl":"https://github.com/DapperLib/Dapper/blob/72a54c475f75e18cb93cba0809d00a5e6e49efd9/Dapper/SqlMapper.cs#L1842-L1878","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before (throws: list is the top-level param)\nvar rows = cnn.Query<Foo>(\"select * from Foo where Id in @Ids\", new[] { 1, 2, 3 });\n// after\nvar rows = cnn.Query<Foo>(\"select * from Foo where Id in @Ids\", new { Ids = new[] { 1, 2, 3 } });","handlingStrategy":"validation","validationCode":"// Never pass a raw list/array as the top-level param to Query; wrap it.\nvar p = new { Ids = theList };\nvar rows = cnn.Query<Foo>(\"select * from Foo where Id in @Ids\", p);","typeGuard":"static bool IsMultiExecParam(object? param) => param is IEnumerable and not string and not IDynamicParameters and not IEnumerable<KeyValuePair<string,object>>;","tryCatchPattern":null,"preventionTips":["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."],"tags":["dapper","parameters","multiexec","argument"],"backgroundTag":null,"analyzedSha":"72a54c475f75e18cb93cba0809d00a5e6e49efd9","analyzedAt":"2026-08-13T14:18:18.115Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}