dotnet/efcore · error · InvalidOperationException
Complex property '{complexProperty}' cannot use 'HasJsonProp
Error message
Complex property '{complexProperty}' cannot use 'HasJsonPropertyName()' because it is not contained within a JSON-mapped type. Use 'ToJson()' to map the complex property to a JSON column, or ensure it is contained within a type that is mapped to JSON. What it means
ValidatePropertyMapping (RelationalModelValidator.cs:293-298) throws when a complex property has a HasJsonPropertyName configured but its declaring type is NOT mapped to JSON. HasJsonPropertyName only makes sense for a property nested inside a JSON document; without a containing JSON column there is nowhere for the JSON key to live, so the configuration is rejected.
Source
Thrown at src/EFCore.Relational/Infrastructure/RelationalModelValidator.cs:295
{
throw new InvalidOperationException(
RelationalStrings.ComplexPropertyOptionalTableSharing(complexProperty.ComplexType.DisplayName(), complexProperty.Name));
}
if (complexProperty.GetJsonPropertyName() != null)
{
if (complexProperty.ComplexType.FindAnnotation(RelationalAnnotationNames.ContainerColumnName)?.Value is string columnName)
{
throw new InvalidOperationException(
RelationalStrings.ComplexPropertyBothJsonColumnAndJsonPropertyName(
$"{complexProperty.DeclaringType.DisplayName()}.{complexProperty.Name}",
columnName,
complexProperty.GetJsonPropertyName()));
}
if (!complexProperty.DeclaringType.IsMappedToJson())
{
throw new InvalidOperationException(
RelationalStrings.ComplexPropertyJsonPropertyNameWithoutJsonMapping(
$"{complexProperty.DeclaringType.DisplayName()}.{complexProperty.Name}"));
}
}
if (complexProperty.ComplexType.IsMappedToJson())
{
if (!complexProperty.DeclaringType.IsMappedToJson()
&& complexProperty.DeclaringType is IComplexType)
{
// Issue #36558
throw new InvalidOperationException(
RelationalStrings.NestedComplexPropertyJsonWithTableSharing(
$"{complexProperty.DeclaringType.DisplayName()}.{complexProperty.Name}",
complexProperty.DeclaringType.DisplayName()));
}
ValidateJsonProperties(complexProperty.ComplexType);View on GitHub (pinned to dbf9771522)
Solutions
- Map the containing type to JSON: add ToJson() on the root complex property/entity so the HasJsonPropertyName has a home.
- If the property should remain table-mapped (flattened to columns), remove HasJsonPropertyName() and use HasColumnName() instead.
- Ensure the entire chain from the entity root down is JSON-mapped before setting JSON property names on nested members.
Example fix
// before - HasJsonPropertyName with no JSON container
modelBuilder.Entity<Customer>().OwnsOne(c => c.Profile, p =>
{
p.HasJsonPropertyName("profile"); // Customer not mapped to JSON -> throws
});
// after - either map container to JSON
modelBuilder.Entity<Customer>().OwnsOne(c => c.Details, d =>
{
d.ToJson("DetailsJson");
d.OwnsOne(c => c.Profile, p => p.HasJsonPropertyName("profile"));
});
// OR drop HasJsonPropertyName and use column mapping for table-shared complex type Defensive patterns
Strategy: validation
Validate before calling
foreach (var et in context.Model.GetEntityTypes())
{
foreach (var cp in et.GetComplexProperties())
{
if (cp.GetJsonPropertyName() != null && !cp.DeclaringType.IsMappedToJson())
{
// will throw - map the containing type to JSON or use HasColumnName instead.
}
}
} Prevention
- Only set HasJsonPropertyName when the containing type is JSON-mapped.
- Use HasColumnName() for table-flattened complex properties.
- Verify the whole JSON chain is rooted before setting nested JSON names.
When it happens
Trigger: Calling HasJsonPropertyName("key") on a complex property whose owning entity/complex type is mapped to a regular table (not via ToJson). Thrown at model validation.
Common situations: Configuring JSON property names on complex types that are table-mapped; applying a HasJsonPropertyName convention to non-JSON entities; partial JSON migration where the root ToJson() was forgotten.
Related errors
- The property '{property}' on type '{type}' is mapped to a JS
- The key {keyProperties} on the entity type '{entityType}' ca
- The optional complex property '{type}.{property}' is mapped
- Complex property '{complexProperty}' cannot have both a JSON
- Complex property '{complexProperty}' is mapped to JSON but i
AI-assisted analysis of dotnet/efcore@dbf9771522 (2026-08-06).
Data as JSON: /api/errors/afd65db968c25d12.
Report an issue: GitHub.