dotnet/efcore · error · InvalidOperationException
The property '{keyProperty}' cannot be configured as 'ValueG
Error message
The property '{keyProperty}' cannot be configured as 'ValueGeneratedOnUpdate' or 'ValueGeneratedOnAddOrUpdate' because it's part of a key and its value cannot be changed after the entity has been added to the store. What it means
Key property values must be immutable after the entity is inserted because they identify the row. The validator at line 1004-1009 throws when a key property has the ValueGenerated.OnUpdate flag set (via ValueGeneratedOnUpdate or ValueGeneratedOnAddOrUpdate) and is not an ordinal key property (used internally for some patterns). Allowing the database to change a key on update would break identity tracking and FK integrity.
Source
Thrown at src/EFCore.Relational/Infrastructure/RelationalModelValidator.cs:1008
{
logger.ModelValidationKeyDefaultValueWarning(propertyWithDefault);
}
}
/// <summary>
/// Validates that a key doesn't have mutable properties.
/// </summary>
/// <param name="key">The key to validate.</param>
/// <param name="logger">The logger to use.</param>
protected override void ValidateMutableKey(
IKey key,
IDiagnosticsLogger<DbLoggerCategory.Model.Validation> logger)
{
var mutableProperty = key.Properties.FirstOrDefault(p => p.ValueGenerated.HasFlag(ValueGenerated.OnUpdate));
if (mutableProperty != null
&& !mutableProperty.IsOrdinalKeyProperty())
{
throw new InvalidOperationException(CoreStrings.MutableKeyProperty(mutableProperty.Name));
}
}
/// <summary>
/// Validates a single table and all entity types mapped to it.
/// </summary>
/// <param name="mappedTypes">The entity types mapped to the table.</param>
/// <param name="table">The table identifier.</param>
/// <param name="logger">The logger to use.</param>
protected virtual void ValidateTable(
IReadOnlyList<IEntityType> mappedTypes,
in StoreObjectIdentifier table,
IDiagnosticsLogger<DbLoggerCategory.Model.Validation> logger)
{
var nonJsonMappedTypes = mappedTypes.Where(e => !e.IsMappedToJson()).ToList();
if (nonJsonMappedTypes.Count > 0)
{
ValidateSharedTableCompatibility(nonJsonMappedTypes, table, logger);View on GitHub (pinned to dbf9771522)
Solutions
- Use .ValueGeneratedOnAdd() instead of .ValueGeneratedOnAddOrUpdate()/.ValueGeneratedOnUpdate() for the key property.
- If the key genuinely should change (rare), reconsider whether it is actually a key — restructure so the mutable column is a non-key property.
- Remove explicit ValueGenerated configuration and let the default conventions (e.g. identity) apply.
Example fix
// before
modelBuilder.Entity<Order>()
.Property(p => p.Id)
.ValueGeneratedOnAddOrUpdate(); // Id is the PK
// after
modelBuilder.Entity<Order>()
.Property(p => p.Id)
.ValueGeneratedOnAdd(); Defensive patterns
Strategy: validation
Validate before calling
foreach (var et in modelBuilder.Model.GetEntityTypes())
{
var pk = et.FindPrimaryKey();
if (pk == null) continue;
foreach (var prop in pk.Properties)
{
if ((prop.ValueGenerated & ValueGenerated.OnUpdate) != 0
&& !prop.IsOrdinalKeyProperty())
{
throw new InvalidOperationException(
$"Key property '{prop.Name}' on {et.Name} must not be ValueGeneratedOnUpdate/AddOrUpdate.");
}
}
} Prevention
- Use ValueGeneratedOnAdd (not AddOrUpdate/OnUpdate) for identity/sequence key columns.
- Audit any custom conventions that set ValueGenerated to ensure they skip key properties.
- If a column must change on update, model it as a non-key property.
When it happens
Trigger: Calling `.ValueGeneratedOnUpdate()` or `.ValueGeneratedOnAddOrUpdate()` on a property that participates in the primary key (or any key). Also happens implicitly when a convention or provider applies these flags to a key column.
Common situations: Misconfiguring a primary key as `ValueGeneratedOnAddOrUpdate` instead of `ValueGeneratedOnAdd`; migrating a model where the key was previously non-generated; a custom convention setting OnUpdate on key properties.
Related errors
- The entity type '{entityType}' is mapped to the DbFunction n
- The entity type '{entityType}' was configured to use some st
- The entity type '{entityType}' was configured to use '{sproc
- The keyless entity type '{entityType}' was configured to use
- The property '{entityType}.{property}' is mapped to an outpu
AI-assisted analysis of dotnet/efcore@dbf9771522 (2026-08-06).
Data as JSON: /api/errors/79407bd87962f3f4.
Report an issue: GitHub.