{"record":{"id":"be9375e7f6adffd4","repo":"dotnet/efcore","slug":"couldn-t-find-single-add-method-on-type-type-nam","errorCode":null,"errorMessage":"Couldn't find single Add method on type '{type.Name}', required for list initializer","messagePattern":"Couldn't find single Add method on type '(.+?)', required for list initializer","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/EFCore.Design/Query/Internal/CSharpToLinqTranslator.cs","lineNumber":882,"sourceCode":"                            _ => throw new InvalidOperationException(\n                                $\"ObjectCreation: unsupported initializer for member of type '{lValueSymbol?.GetType().Name}': {e}\")\n                        };\n\n                        return memberInfo is null\n                            ? throw new InvalidOperationException(\n                                $\"ObjectCreation: couldn't find initialized member '{lValueSymbol.Name}': {e}\")\n                            : Bind(memberInfo, Visit(value));\n                    }));\n\n            // Non-assignment initializer => list initializer (new List<int> { 1, 2, 3 })\n            default:\n                // Find the correct Add() method on the collection type\n                // TODO: This doesn't work if there are multiple Add() methods (contrived). Complete solution would be to find the base\n                // TODO: type for all initializer expressions and find an Add overload of that type (or a superclass thereof)\n                var addMethod = type.GetMethods().SingleOrDefault(m => m.Name == \"Add\" && m.GetParameters().Length == 1);\n                if (addMethod is null)\n                {\n                    throw new InvalidOperationException(\n                        $\"Couldn't find single Add method on type '{type.Name}', required for list initializer\");\n                }\n\n                // TODO: Dictionary initializer, where each ElementInit has more than one expression\n\n                return ListInit(\n                    newExpression,\n                    objectCreation.Initializer.Expressions.Select(e => ElementInit(addMethod, Visit(e))));\n        }\n    }\n\n    /// <summary>\n    ///     This is an internal API that supports the Entity Framework Core infrastructure and not subject to\n    ///     the same compatibility standards as public APIs. It may be changed or removed without notice in\n    ///     any release. You should only use it directly in your code with extreme caution and knowing that\n    ///     doing so can result in application failures when updating to a new Entity Framework Core release.\n    /// </summary>\n    public override Expression VisitParenthesizedExpression(ParenthesizedExpressionSyntax parenthesized)","sourceCodeStart":864,"sourceCodeEnd":900,"githubUrl":"https://github.com/dotnet/efcore/blob/3a2006ef569de08368d59db5e1468aa8f407e4f8/src/EFCore.Design/Query/Internal/CSharpToLinqTranslator.cs#L864-L900","documentation":"Thrown when the translator tries to build a collection initializer (e.g. `new List<int> { 1, 2, 3 }`) but cannot find exactly one Add method with a single parameter on the created type via SingleOrDefault. This happens when the type has zero Add methods (not a collection), or has multiple Add(T) overloads making SingleOrDefault throw — note the code uses SingleOrDefault which returns null for zero matches but throws InvalidOperationException for multiple matches. The null-check then throws the documented error.","triggerScenarios":"A precompiled query creates a collection with an element initializer where: the type has no single-parameter Add method (not IEnumerable-compatible), the type has multiple single-parameter Add overloads (e.g. a custom collection with Add(int), Add(string) where the element type is ambiguous), or the type is a dictionary with Add(key, value) (two parameters, so no single-param match). SingleOrDefault throws on ambiguity before the null check.","commonSituations":"Creating dictionaries with collection initializers inside precompiled queries (`new Dictionary<int,string> { { 1, \"a\" } }` — Add has 2 params); custom collection types with multiple Add overloads; creating types that look like collections but lack a standard Add method; initializing HashSet with complex element types where the Add method has optional parameters creating multiple single-param signatures.","solutions":["For dictionaries: create and populate the dictionary outside the precompiled query body and capture it as a variable, since the TODO comment confirms dictionary initializers are unsupported.","For custom collections with multiple Add overloads: reduce to a single Add(T) method or create the collection outside the query.","For non-collection types: don't use collection-initializer syntax — construct and populate via explicit method calls outside the query.","Use List<T> or arrays instead of specialized collection types inside precompiled queries.","If a collection must be built in-query, use Enumerable.Range/Repeat/Empty factory methods instead of initializer syntax."],"exampleFix":"// before — dictionary initializer inside query\nvar query = ctx.Rules.Select(r => new Dictionary<int, string> { { r.Id, r.Name } });\n\n// after — build outside query, or use a different pattern\nvar map = ctx.Rules.ToDictionary(r => r.Id, r => r.Name);","handlingStrategy":"validation","validationCode":"// Before precompiling, check collection initializers for Add method ambiguity\nforeach (var objCreation in querySyntaxTree.DescendantNodes().OfType<ObjectCreationExpressionSyntax>())\n{\n    if (objCreation.Initializer?.Expressions is null or [] or [AssignmentExpressionSyntax, ..]) continue;\n    // This is a collection initializer path\n    var type = semanticModel.GetSymbolInfo(objCreation).Symbol is IMethodSymbol ctor\n        ? ResolveTypeForCheck(ctor.ContainingType) : null;\n    if (type is null) continue;\n    var addMethods = type.GetMethods().Where(m => m.Name == \"Add\" && m.GetParameters().Length == 1).ToList();\n    if (addMethods.Count != 1)\n        ReportError($\"Type '{type.Name}' has {addMethods.Count} single-param Add methods — collection initializer unsupported\");\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Avoid dictionary initializers (new Dictionary<K,V> { { k, v } }) inside precompiled queries — build dictionaries outside.","Use List<T> or arrays instead of custom or complex collection types.","Ensure custom collections have exactly one single-parameter Add method.","Prefer Enumerable factory methods (Enumerable.Range, Repeat, Empty) over collection initializers in queries.","Build collections outside the precompiled query body and capture them as variables."],"tags":["precompiled-queries","roslyn","object-creation","collection-initializer","reflection","expression-tree"],"backgroundTag":null,"analyzedSha":"3a2006ef569de08368d59db5e1468aa8f407e4f8","analyzedAt":"2026-08-11T23:42:04.146Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}