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
- Verify assembly version consistency between compile-time and precompilation-time references.
- If the constructor is internal, add InternalsVisibleTo for the precompilation assembly or make the constructor public.
- Avoid constructors with ref/out parameters in precompiled queries.
- 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.
- 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
- Avoid constructors with ref/out parameters in precompiled queries.
- Keep package versions consistent between compile-time and precompile-time.
- Make internal constructors public or add InternalsVisibleTo.
- For structs, prefer the parameterless constructor or ensure the parameterized constructor is accessible.
- Avoid constructing objects whose parameter types are interfaces or abstract types that may resolve differently.
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
- Couldn't find single Add method on type
- ObjectCreation: couldn't find IMethodSymbol for constructor
- Invocation: couldn't find method
- Invocation: Found matches for generic method
- MemberAccess: couldn't find member
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)