dotnet/efcore · error · InvalidOperationException

The complex types '{complexType1}' and '{complexType2}' are

Error message

The complex types '{complexType1}' and '{complexType2}' are being assigned, but the latter is lacking property '{property}' of the former.

What it means

Thrown when assigning one complex type to another during ExecuteUpdate and the value (right-hand) complex type is missing a property that exists on the target (left-hand) complex type. Because complex types are structurally compared property-by-property, an asymmetric shape is rejected.

Source

Thrown at src/EFCore.Relational/Query/RelationalQueryableMethodTranslatingExpressionVisitor.ExecuteUpdate.cs:554

                    {
                        throw new InvalidOperationException(
                            RelationalStrings.ExecuteUpdateOverJsonIsNotSupported(nestedTargetComplexProperty.ComplexType.DisplayName()));
                    }

                    var nestedTargetExpression =
                        (StructuralTypeShaperExpression)targetProjection.BindComplexProperty(nestedTargetComplexProperty);

                    // If the value expression is a shaper with its own complex type (as opposed to a constant/parameter), we're assigning
                    // one (modeled) column to another. In that case, find the corresponding property on the value complex type (which is
                    // different than the target complex type, despite the two having the same CLR type, e.g. compare ShippingAddress to
                    // BillingAddress).
                    // Otherwise, if the value expression is a constant/parameter, just use the target complex property.
                    var nestedValueComplexProperty = valueExpression is StructuralTypeShaperExpression
                    {
                        StructuralType: IComplexType valueNestedComplexType
                    }
                        ? valueNestedComplexType!.FindComplexProperty(nestedTargetComplexProperty.Name)
                        ?? throw new InvalidOperationException(
                            RelationalStrings.IncompatibleComplexTypesInAssignment(
                                targetNestedComplexType.DisplayName(), valueNestedComplexType.DisplayName(),
                                nestedTargetComplexProperty.Name))
                        : nestedTargetComplexProperty;

                    var nestedValueExpression = CreateComplexPropertyAccessExpression(valueExpression, nestedValueComplexProperty);

                    ProcessComplexType(nestedTargetExpression, nestedValueExpression);
                }

                Expression CreatePropertyAccessExpression(Expression target, IProperty property)
                {
                    return target is LambdaExpression lambda
                        ? Expression.Lambda(Core(lambda.Body, property), lambda.Parameters[0])
                        : Core(target, property);

                    Expression Core(Expression target, IProperty property)
                    {

View on GitHub (pinned to 3a2006ef56)

Solutions

  1. Make both complex types structurally identical (add the missing property to the value complex type, or remove it from the target).
  2. Assign property-by-property instead of whole-complex-type assignment.
  3. If using the same CLR type for both, ensure model configuration defines the same set of properties on each complex type.

Example fix

// before
.ExecuteUpdate(s => s.SetProperty(e => e.ShippingAddress, e => e.BillingAddress));
// ShippingAddress has Zip, BillingAddress does not
// after
modelBuilder.Entity<Order>().ComplexProperty(o => o.BillingAddress, b => b.Property(x => x.Zip).IsRequired());
// or assign field by field
.ExecuteUpdate(s => s
    .SetProperty(e => e.ShippingAddress.Street, e => e.BillingAddress.Street)
    .SetProperty(e => e.ShippingAddress.City, e => e.BillingAddress.City));
Defensive patterns

Strategy: validation

Validate before calling

// Assert two complex types have identical property sets before assignment.
static bool AreShapeCompatible(IComplexType a, IComplexType b)
{
    var ap = a.GetProperties().Select(p => p.Name).ToHashSet();
    var bp = b.GetProperties().Select(p => p.Name).ToHashSet();
    return ap.SetEquals(bp);
}

Prevention

When it happens

Trigger: SetProperty(e => e.ShippingAddress, e => e.BillingAddress) where ShippingAddress and BillingAddress are different complex types that share a CLR type but one is missing a property defined on the other (e.g. ShippingAddress has Zip but BillingAddress does not). The nested-complex-property lookup returns null and fires this.

Common situations: Using two distinct complex types with the same CLR type but different property sets; refactoring one complex type without updating the other; assigning between complex types that drifted in schema.

Related errors


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