dotnet/efcore · error · InvalidOperationException

Couldn't find single Add method on type

Error message

Couldn't find single Add method on type '{type.Name}', required for list initializer

What it means

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.

Solutions

  1. 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.
  2. For custom collections with multiple Add overloads: reduce to a single Add(T) method or create the collection outside the query.
  3. For non-collection types: don't use collection-initializer syntax — construct and populate via explicit method calls outside the query.
  4. Use List<T> or arrays instead of specialized collection types inside precompiled queries.
  5. If a collection must be built in-query, use Enumerable.Range/Repeat/Empty factory methods instead of initializer syntax.

Example fix

// before — dictionary initializer inside query
var query = ctx.Rules.Select(r => new Dictionary<int, string> { { r.Id, r.Name } });

// after — build outside query, or use a different pattern
var map = ctx.Rules.ToDictionary(r => r.Id, r => r.Name);
Defensive patterns

Strategy: validation

Validate before calling

// Before precompiling, check collection initializers for Add method ambiguity
foreach (var objCreation in querySyntaxTree.DescendantNodes().OfType<ObjectCreationExpressionSyntax>())
{
    if (objCreation.Initializer?.Expressions is null or [] or [AssignmentExpressionSyntax, ..]) continue;
    // This is a collection initializer path
    var type = semanticModel.GetSymbolInfo(objCreation).Symbol is IMethodSymbol ctor
        ? ResolveTypeForCheck(ctor.ContainingType) : null;
    if (type is null) continue;
    var addMethods = type.GetMethods().Where(m => m.Name == "Add" && m.GetParameters().Length == 1).ToList();
    if (addMethods.Count != 1)
        ReportError($"Type '{type.Name}' has {addMethods.Count} single-param Add methods — collection initializer unsupported");
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of dotnet/efcore@3a2006ef56 (2026-08-11). Data as JSON: /api/errors/be9375e7f6adffd4. Report an issue: GitHub.

Appendix: source

Thrown at src/EFCore.Design/Query/Internal/CSharpToLinqTranslator.cs:882

                            _ => throw new InvalidOperationException(
                                $"ObjectCreation: unsupported initializer for member of type '{lValueSymbol?.GetType().Name}': {e}")
                        };

                        return memberInfo is null
                            ? throw new InvalidOperationException(
                                $"ObjectCreation: couldn't find initialized member '{lValueSymbol.Name}': {e}")
                            : Bind(memberInfo, Visit(value));
                    }));

            // Non-assignment initializer => list initializer (new List<int> { 1, 2, 3 })
            default:
                // Find the correct Add() method on the collection type
                // TODO: This doesn't work if there are multiple Add() methods (contrived). Complete solution would be to find the base
                // TODO: type for all initializer expressions and find an Add overload of that type (or a superclass thereof)
                var addMethod = type.GetMethods().SingleOrDefault(m => m.Name == "Add" && m.GetParameters().Length == 1);
                if (addMethod is null)
                {
                    throw new InvalidOperationException(
                        $"Couldn't find single Add method on type '{type.Name}', required for list initializer");
                }

                // TODO: Dictionary initializer, where each ElementInit has more than one expression

                return ListInit(
                    newExpression,
                    objectCreation.Initializer.Expressions.Select(e => ElementInit(addMethod, Visit(e))));
        }
    }

    /// <summary>
    ///     This is an internal API that supports the Entity Framework Core infrastructure and not subject to
    ///     the same compatibility standards as public APIs. It may be changed or removed without notice in
    ///     any release. You should only use it directly in your code with extreme caution and knowing that
    ///     doing so can result in application failures when updating to a new Entity Framework Core release.
    /// </summary>
    public override Expression VisitParenthesizedExpression(ParenthesizedExpressionSyntax parenthesized)

View on GitHub (pinned to 3a2006ef56)