{"record":{"id":"a625818103e96275","repo":"dotnet/efcore","slug":"the-short-name-for-entitytype1-is-discrimina","errorCode":null,"errorMessage":"The short name for '{entityType1}' is '{discriminatorValue}' which is the same for '{entityType2}'. Every concrete entity type in the hierarchy must have a unique short name. Either rename one of the types or call 'modelBuilder.Entity<TEntity>().Metadata.SetDiscriminatorValue(\"NewShortName\")'.","messagePattern":"The short name for '(.+?)' is '(.+?)' which is the same for '(.+?)'\\. Every concrete entity type in the hierarchy must have a unique short name\\. Either rename one of the types or call 'modelBuilder\\.Entity<TEntity>\\(\\)\\.Metadata\\.SetDiscriminatorValue\\(\"NewShortName\"\\)'\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/EFCore.Relational/Infrastructure/RelationalModelValidator.cs","lineNumber":2157,"sourceCode":"                    ValidateDiscriminatorValues(complexProperty.ComplexType);\n                }\n\n                var discriminatorValue = derivedType.GetDiscriminatorValue();\n                if (!derivedType.ClrType.IsInstantiable()\n                    || discriminatorValue is null)\n                {\n                    continue;\n                }\n\n                if (discriminatorValue is not string valueString)\n                {\n                    throw new InvalidOperationException(\n                        RelationalStrings.NonTphDiscriminatorValueNotString(discriminatorValue, derivedType.DisplayName()));\n                }\n\n                if (discriminatorValues.TryGetValue(valueString, out var duplicateEntityType))\n                {\n                    throw new InvalidOperationException(\n                        RelationalStrings.EntityShortNameNotUnique(\n                            derivedType.Name, discriminatorValue, duplicateEntityType.Name));\n                }\n\n                discriminatorValues[valueString] = derivedType;\n            }\n        }\n    }\n\n    /// <summary>\n    ///     Validates the key value generation is valid.\n    /// </summary>\n    /// <param name=\"key\">The key.</param>\n    /// <param name=\"logger\">The logger to use.</param>\n    protected virtual void ValidateValueGeneration(\n        IKey key,\n        IDiagnosticsLogger<DbLoggerCategory.Model.Validation> logger)\n    {","sourceCodeStart":2139,"sourceCodeEnd":2175,"githubUrl":"https://github.com/dotnet/efcore/blob/3a2006ef569de08368d59db5e1468aa8f407e4f8/src/EFCore.Relational/Infrastructure/RelationalModelValidator.cs#L2139-L2175","documentation":"Thrown inside ValidateDiscriminatorValues when two concrete derived types in a non-TPH hierarchy resolve to the same string discriminator value (the duplicate is found via discriminatorValues.TryGetValue(valueString, ...)). In TPT/TPC the discriminator value defaults to the entity short name (the simple type name), so two types sharing a short name collide.","triggerScenarios":"Two concrete entity types in the same hierarchy have identical simple names (e.g. NamespaceA.User and NamespaceB.User both derive from Person), or two types are explicitly assigned the same discriminator value via SetDiscriminatorValue.","commonSituations":"Cross-namespace name collisions; generated/DTO types with reused names; bulk import of entities where short names repeat; forgetting that the discriminator value is the type name by default.","solutions":["Rename one of the colliding types so the simple names differ.","Assign a unique discriminator value explicitly: modelBuilder.Entity<TEntity>().Metadata.SetDiscriminatorValue(\"NewShortName\").","Move one of the types into a different hierarchy or make it standalone."],"exampleFix":"// before\nnamespace App.Admin { class User : Person {} }\nnamespace App.Store { class User : Person {} } // both short name \"User\" -> throws 423\n\n// after\nmodelBuilder.Entity<App.Admin.User>().Metadata.SetDiscriminatorValue(\"AdminUser\");\nmodelBuilder.Entity<App.Store.User>().Metadata.SetDiscriminatorValue(\"StoreUser\");","handlingStrategy":"validation","validationCode":"var byShortName = new Dictionary<string, List<string>>();\nforeach (var entityType in modelBuilder.Model.GetEntityTypes()\n    .Where(t => t.BaseType != null && t.ClrType.IsInstantiable()))\n{\n    var root = entityType.GetRootType();\n    if (root.GetMappingStrategy() == RelationalAnnotationNames.TphMappingStrategy) continue;\n    var value = entityType.GetDiscriminatorValue()?.ToString() ?? entityType.ShortName();\n    byShortName.TryAdd(value, new());\n    byShortName[value].Add(entityType.DisplayName());\n}\nvar dup = byShortName.FirstOrDefault(kv => kv.Value.Count > 1);\nif (dup.Key != null)\n    throw new InvalidOperationException($\"Duplicate short name '{dup.Key}': {string.Join(\", \", dup.Value)}\");","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Avoid reusing the same simple type name for sibling entity types in a hierarchy.","If names must repeat across namespaces, assign explicit unique discriminator values.","Run a naming-collision check in a model test."],"tags":["ef-core","model-validation","mapping","inheritance","tpt","tpc","discriminator","naming"],"backgroundTag":null,"analyzedSha":"3a2006ef569de08368d59db5e1468aa8f407e4f8","analyzedAt":"2026-08-11T23:42:04.146Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}