dotnet/efcore · error · InvalidOperationException
A seed entity for entity type
Error message
A seed entity for entity type '{entityType}' has the same key value {keyValue} as another seed entity mapped to the same table '{table}', but have different values for the column '{column}' - '{firstValue}', '{secondValue}'. What it means
Sensitive variant of the conflicting-seed-values check. Two seed entries share a key (same table) but disagree on the value of a non-key column, so the resulting INSERT/UPDATE would be ambiguous. Because sensitive logging is enabled, EF prints the key, the column name, and both conflicting values to help you reconcile them.
Solutions
- Use the printed key and column to find both seed entries and pick a single authoritative value.
- If one entry should win, delete the other; do not leave conflicting duplicates.
- Make sure both entries agree on every non-key column, or merge them into one entry.
- After fixing, regenerate the migration so the seed snapshot is consistent.
Example fix
// before
modelBuilder.Entity<Product>().HasData(
new Product { Id = 7, Sku = "A1" },
new Product { Id = 7, Sku = "B2" }); // same key, different Sku
// after
modelBuilder.Entity<Product>().HasData(
new Product { Id = 7, Sku = "A1" }); Defensive patterns
Strategy: validation
Validate before calling
// For each entity, ensure no two seed rows share a key while differing elsewhere
static void AssertSeedConsistent<TEntity>(
IEnumerable<TEntity> seed,
Func<TEntity, object> key,
params Func<TEntity, object?>[] columns)
{
foreach (var g in seed.GroupBy(key))
{
var rows = g.ToList();
if (rows.Count <= 1) continue;
foreach (var col in columns)
{
var vals = rows.Select(col).Distinct().ToList();
if (vals.Count > 1)
throw new InvalidOperationException(
$"Conflicting seed value for key {g.Key} on column");
}
}
} Type guard
null
Prevention
- Keep sensitive logging on in dev/test only to catch conflicts early.
- Treat seed data as code: single source of truth, reviewed like migrations.
- Write a test that materializes seed rows and asserts per-key uniqueness across all columns.
When it happens
Trigger: HasData for one entity has two anonymous objects/instances with equal keys but different values for at least one mapped column; sensitiveLoggingEnabled is true (EnableSensitiveDataLogging on). The differ compares each column modification via NormalizeSeedValue and throws on the first mismatch.
Common situations: Seed updated in one place but not another after a column was added; merge conflicts resolved by keeping both seed blocks; enums stored as int where two entries use the same key but different enum values; default-value fallback (ProviderClrType default) colliding with an explicit value.
Related errors
- A seed entity for entity type
- A seed entity for entity type
- The data insertion operation on
- The number of column types
- The number of key values
AI-assisted analysis of dotnet/efcore@3a2006ef56 (2026-08-11).
Data as JSON: /api/errors/97e9ce03a9f1dc74.
Report an issue: GitHub.
Appendix: source
Thrown at src/EFCore.Relational/Migrations/Internal/MigrationsModelDiffer.cs:2010
if (column.DefaultValue != null)
{
value = column.DefaultValue;
}
else if (value == null
&& !column.IsNullable)
{
value = column.ProviderClrType.GetDefaultValue();
}
}
var existingColumnModification = command.ColumnModifications.FirstOrDefault(c => c.ColumnName == column.Name);
if (existingColumnModification != null)
{
if (!Equals(NormalizeSeedValue(existingColumnModification.Value), NormalizeSeedValue(value)))
{
if (sensitiveLoggingEnabled)
{
throw new InvalidOperationException(
RelationalStrings.ConflictingSeedValuesSensitive(
entityType.DisplayName(),
BuildValuesString(key),
table.SchemaQualifiedName,
existingColumnModification.ColumnName,
Convert.ToString(existingColumnModification.Value, CultureInfo.InvariantCulture),
Convert.ToString(value, CultureInfo.InvariantCulture)));
}
throw new InvalidOperationException(
RelationalStrings.ConflictingSeedValues(
entityType.DisplayName(),
table.SchemaQualifiedName,
existingColumnModification.ColumnName));
}
continue;
}View on GitHub (pinned to 3a2006ef56)