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

  1. Use .ValueGeneratedOnAdd() instead of .ValueGeneratedOnAddOrUpdate()/.ValueGeneratedOnUpdate() for the key property.
  2. If the key genuinely should change (rare), reconsider whether it is actually a key — restructure so the mutable column is a non-key property.
  3. 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

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


AI-assisted analysis of dotnet/efcore@dbf9771522 (2026-08-06). Data as JSON: /api/errors/79407bd87962f3f4. Report an issue: GitHub.