dotnet/efcore · error · InvalidOperationException
The key {keyProperties} on the entity type '{entityType}' ca
Error message
The key {keyProperties} on the entity type '{entityType}' cannot be configured because the property '{property}' is contained in a complex type mapped to a JSON column. Keys cannot reference properties that are stored inside a JSON document. What it means
ValidateKey (RelationalModelValidator.cs:223-234) throws when any property participating in a key is declared on a complex type that is mapped to a JSON column. Keys must be addressable as standalone columns (for indexing, FKs, joins), but properties inside a JSON document are embedded and cannot back a key, so the configuration is rejected.
Source
Thrown at src/EFCore.Relational/Infrastructure/RelationalModelValidator.cs:228
{
throw new InvalidOperationException(
RelationalStrings.AutoLoadedJsonProperty(property.Name, structuralType.DisplayName()));
}
}
/// <inheritdoc />
protected override void ValidateKey(
IKey key,
IDiagnosticsLogger<DbLoggerCategory.Model.Validation> logger)
{
base.ValidateKey(key, logger);
foreach (var property in key.Properties)
{
if (property.DeclaringType is IComplexType complexType
&& complexType.IsMappedToJson())
{
throw new InvalidOperationException(
RelationalStrings.KeyPropertyInJsonComplexType(
key.Properties.Format(),
key.DeclaringEntityType.DisplayName(),
property.Name));
}
}
ValidateDefaultValuesOnKey(key, logger);
ValidateValueGeneration(key, logger);
}
/// <summary>
/// Validates a primitive collection property.
/// </summary>
/// <param name="property">The property to validate.</param>
/// <param name="logger">The logger to use.</param>
protected override void ValidatePrimitiveCollection(
IProperty property,View on GitHub (pinned to dbf9771522)
Solutions
- Move the key property out of the JSON-mapped complex type onto the owning entity as a real column.
- If the owned type genuinely needs identity, stop mapping it to JSON and map it to its own table or as table-splitting columns.
- Remove the key configuration that references the JSON-contained property and let EF treat the owned type as a value object.
Example fix
// before
modelBuilder.Entity<Customer>().OwnsOne(c => c.Profile, p =>
{
p.ToJson("ProfileJson");
});
modelBuilder.Entity<Customer>().HasKey(c => new { c.Id, c.Profile.ProfileId }); // ProfileId is in JSON -> throws
// after - promote the key column out of JSON
modelBuilder.Entity<Customer>().Property(c => c.ProfileId).HasColumnName("ProfileId");
modelBuilder.Entity<Customer>().HasKey(c => new { c.Id, c.ProfileId }); Defensive patterns
Strategy: validation
Validate before calling
// Pre-validate: no key property may live in a JSON-mapped complex type.
foreach (var et in context.Model.GetEntityTypes())
{
foreach (var key in et.GetDeclaredKeys())
{
foreach (var p in key.Properties)
{
if (p.DeclaringType is IComplexType ct && ct.IsMappedToJson())
{
// will throw - move this property out of JSON.
}
}
}
} Prevention
- Keep key properties on the owning entity as real columns.
- Don't reference JSON-contained properties in HasKey expressions.
- When moving an owned type to JSON, audit existing key configurations.
When it happens
Trigger: Declaring a key on an entity type that references a property which itself lives inside a JSON-mapped complex type (e.g. an owned JSON type exposes an Id that you tried to make part of the owner's key). Thrown during model validation.
Common situations: Trying to define a composite key that includes an owned JSON entity's Id; refactoring an owned type from table-splitting to JSON while a key reference remained; key conventions picking up a JSON-owned property.
Related errors
- The property '{property}' on type '{type}' is mapped to a JS
- The optional complex property '{type}.{property}' is mapped
- Complex property '{complexProperty}' cannot have both a JSON
- Complex property '{complexProperty}' cannot use 'HasJsonProp
- Complex property '{complexProperty}' is mapped to JSON but i
AI-assisted analysis of dotnet/efcore@dbf9771522 (2026-08-06).
Data as JSON: /api/errors/9244b03da75a397b.
Report an issue: GitHub.