{"record":{"id":"769b164b7bf8f33b","repo":"dotnet/efcore","slug":"a-partition-key-is-defined-on-entity-type-entity","errorCode":null,"errorMessage":"A partition key is defined on entity type '{entityType}', which inherits from '{baseEntityType}'. Partition keys must be defined on the root entity type of a hierarchy.","messagePattern":"A partition key is defined on entity type '(.+?)', which inherits from '(.+?)'\\. Partition keys must be defined on the root entity type of a hierarchy\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/EFCore.Cosmos/Infrastructure/Internal/CosmosModelValidator.cs","lineNumber":458,"sourceCode":"        var idType = idProperty.GetTypeMapping().Converter?.ProviderClrType\n            ?? idProperty.ClrType;\n        if (idType != typeof(string))\n        {\n            throw new InvalidOperationException(\n                CosmosStrings.IdNonStringStoreType(idProperty.Name, entityType.DisplayName(), idType.ShortDisplayName()));\n        }\n\n        var partitionKeyPropertyNames = entityType.GetPartitionKeyPropertyNames();\n        if (partitionKeyPropertyNames.Count == 0)\n        {\n            logger.NoPartitionKeyDefined(entityType);\n        }\n        else\n        {\n            if (entityType.BaseType != null\n                && entityType.FindAnnotation(CosmosAnnotationNames.PartitionKeyNames)?.Value != null)\n            {\n                throw new InvalidOperationException(\n                    CosmosStrings.PartitionKeyNotOnRoot(entityType.DisplayName(), entityType.BaseType.DisplayName()));\n            }\n\n            foreach (var partitionKeyPropertyName in partitionKeyPropertyNames)\n            {\n                var partitionKey = entityType.FindProperty(partitionKeyPropertyName);\n                if (partitionKey == null)\n                {\n                    throw new InvalidOperationException(\n                        CosmosStrings.PartitionKeyMissingProperty(entityType.DisplayName(), partitionKeyPropertyName));\n                }\n\n                var partitionKeyType = (partitionKey.GetTypeMapping().Converter?.ProviderClrType\n                    ?? partitionKey.ClrType).UnwrapNullableType();\n                if (partitionKeyType != typeof(string)\n                    && !partitionKeyType.IsNumeric()\n                    && partitionKeyType != typeof(bool))\n                {","sourceCodeStart":440,"sourceCodeEnd":476,"githubUrl":"https://github.com/dotnet/efcore/blob/dbf9771522148d61a2467854921bd5dc6f6e6916/src/EFCore.Cosmos/Infrastructure/Internal/CosmosModelValidator.cs#L440-L476","documentation":"Thrown by ValidateKeys when an entity type that has a BaseType (a derived type in an inheritance hierarchy) directly carries the PartitionKeyNames annotation. Partition keys are container-scoped and must be declared on the root entity type of the hierarchy; derived types inherit the partition key. The check uses FindAnnotation to detect a locally-set (not inherited) partition key.","triggerScenarios":"Calling HasPartitionKey(...) on an EntityTypeBuilder whose entity derives from a base entity (TPH hierarchy sharing a container).","commonSituations":"Applying a generic 'configure partition key' helper to every entity in a hierarchy; splitting configuration across partial OnModelCreating methods where the derived config runs.","solutions":["Move the HasPartitionKey call to the root entity type of the hierarchy.","Guard shared config helpers with `if (entityType.BaseType == null)` before setting partition keys.","Remove the partition-key annotation from the derived type."],"exampleFix":"// before\nmodelBuilder.Entity<Manager>().HasPartitionKey(m => m.DepartmentId); // Manager derives from Employee\n\n// after\nmodelBuilder.Entity<Employee>().HasPartitionKey(e => e.DepartmentId);","handlingStrategy":"validation","validationCode":"using var ctx = new MyContext();\nforeach (var e in ctx.Model.GetEntityTypes().Where(t => t.BaseType is not null))\n{\n    Debug.Assert(e.FindAnnotation(\"Cosmos:PartitionKeyNames\") is null,\n        $\"{e.Name} (derived) must not declare a partition key; set it on the root.\");\n}","typeGuard":"static bool IsHierarchyRoot(Microsoft.EntityFrameworkCore.Metadata.IEntityType e) => e.BaseType is null;","tryCatchPattern":"try { ctx.Model.GetModel(); }\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"Partition keys must be defined on the root\"))\n{\n    logger.LogError(ex, \"HasPartitionKey was called on a derived entity type\");\n    throw;\n}","preventionTips":["Only call HasPartitionKey on the root entity of a hierarchy.","Guard shared config helpers with a BaseType == null check.","Test that no derived type carries the partition-key annotation locally."],"tags":["cosmos","configuration","model-validation","partition-key","inheritance"],"analyzedSha":"dbf9771522148d61a2467854921bd5dc6f6e6916","analyzedAt":"2026-08-06T20:46:03.226Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}