dotnet/efcore · error · InvalidOperationException

ObjectCreation: Missing constructor

Error message

ObjectCreation: Missing constructor: {objectCreation}

What it means

Thrown when Roslyn resolved the constructor symbol but Type.GetConstructor(parameterTypes) returned null AND the constructor is not a parameterless struct constructor. The translator tries to find the reflection constructor matching the symbol's parameter types; if it can't find it, it falls back to New(type) for parameterless struct constructors. If neither path works, it throws InvalidOperationException.

Solutions

  1. Verify assembly version consistency between compile-time and precompilation-time references.
  2. If the constructor is internal, add InternalsVisibleTo for the precompilation assembly or make the constructor public.
  3. Avoid constructors with ref/out parameters in precompiled queries.
  4. Check that ResolveType maps the constructor's parameter types correctly — investigate by examining the Roslyn parameter types vs. the loaded assembly's constructor parameter types.
  5. If creating a struct, ensure it has a usable parameterless constructor or provide a constructor that reflection can find.

Example fix

// before — constructor with ref param, reflection can't find it
var query = ctx.Items.Select(i => new Wrapper(ref i.Data));

// after — use a constructor with standard value params
var query = ctx.Items.Select(i => new Wrapper(i.Data));
Defensive patterns

Strategy: validation

Validate before calling

// Before precompiling, verify constructors are findable via reflection
foreach (var objCreation in querySyntaxTree.DescendantNodes().OfType<ObjectCreationExpressionSyntax>())
{
    if (semanticModel.GetSymbolInfo(objCreation).Symbol is IMethodSymbol ctor)
    {
        var type = ResolveTypeForCheck(ctor.ContainingType);
        var paramTypes = ctor.Parameters.Select(p => ResolveTypeForCheck(p.Type)).ToArray();
        var found = type.GetConstructor(paramTypes);
        if (found is null && paramTypes.Length > 0)
            ReportError($"Constructor for {type.Name} not found via reflection");
    }
}

Prevention

When it happens

Trigger: A precompiled query creates an object where: the constructor's parameter types as resolved by ResolveType don't match the actual CLR constructor's parameter types (type-forwarding, version skew), the constructor is private/protected and inaccessible via default GetConstructor, or the constructor has ref/out parameters that change the type signature. The parameterless fallback only applies to structs.

Common situations: Creating objects whose constructors accept interfaces or abstract types where ResolveType maps differently; version skew between the referenced package and loaded assembly changing constructor signatures; creating objects with constructors that have ref/out parameters; creating objects of types with only internal constructors without InternalsVisibleTo.

Related errors


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

Appendix: source

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

        {
            throw new InvalidOperationException($"ObjectCreation: couldn't find IMethodSymbol for constructor: {objectCreation}");
        }

        Check.DebugAssert(constructorSymbol.MethodKind == MethodKind.Constructor);

        var type = ResolveType(constructorSymbol.ContainingType);

        // Find the reflection constructor that matches the constructor symbol's signature
        var parameterTypes = constructorSymbol.Parameters.Select(ps => ResolveType(ps.Type)).ToArray();
        var constructor = type.GetConstructor(parameterTypes);

        var newExpression = constructor is not null
            ? New(
                constructor,
                objectCreation.ArgumentList?.Arguments.Select(a => Visit(a)) ?? [])
            : parameterTypes.Length == 0 // For structs, there's no actual parameterless constructor
                ? New(type)
                : throw new InvalidOperationException($"ObjectCreation: Missing constructor: {objectCreation}");

        switch (objectCreation.Initializer)
        {
            // No initializers, just return the NewExpression
            case null or { Expressions: [] }:
                return newExpression;

            // Assignment initializer (new Blog { Name = "foo" })
            case { Expressions: [AssignmentExpressionSyntax, ..] }:
                return MemberInit(
                    newExpression,
                    objectCreation.Initializer.Expressions.Select(e =>
                    {
                        if (e is not AssignmentExpressionSyntax { Left: var lValue, Right: var value })
                        {
                            throw new NotSupportedException(
                                $"ObjectCreation: non-assignment initializer expression of type '{e.GetType().Name}': {objectCreation}");
                        }

View on GitHub (pinned to 3a2006ef56)