dotnet/efcore · error · InvalidOperationException

The partition key properties for entity type

Error message

The partition key properties for entity type '{entityType1}' are '{props1}', while the partition key properties for entity type '{entityType2}' are '{props2}', and both entity types are mapped to the container '{containerName}'. All entity types mapped to the same container must have compatible partition keys defined.

What it means

CosmosModelValidator.ValidateSharedContainerCompatibility throws InvalidOperationException(CosmosStrings.NoPartitionKey) when two entity types mapped to the same container have partition key property sets of different counts. Cosmos requires every entity type sharing a container to declare the same partition key shape (same number of properties). The check fails when partitionKeyStoreNames.Count != storeNames.Count for a subsequent entity type in the same container.

Solutions

  1. Align the partition key declaration on every entity type sharing the container: same number of properties, same order.
  2. If the entity types genuinely need different partition keys, map them to separate containers.
  3. Centralize partition key configuration in a shared convention or IEntityTypeConfiguration so all types in a container receive the same shape.
  4. After changing partition key configuration, re-run model validation at startup (EnsureCreated or a no-op query) to catch the mismatch early.

Example fix

// before - throws: same container, different partition key counts
modelBuilder.Entity<A>().HasPartitionKey(a => a.TenantId).ToContainer("Shared");
modelBuilder.Entity<B>().ToContainer("Shared"); // no partition key

// after - align partition keys across the shared container
modelBuilder.Entity<A>().HasPartitionKey(a => a.TenantId).ToContainer("Shared");
modelBuilder.Entity<B>().HasPartitionKey(b => b.TenantId).ToContainer("Shared");
Defensive patterns

Strategy: validation

Validate before calling

// Align partition keys before model validation.
static void AlignPartitionKeys(ModelBuilder mb, string container, params string[] props)
{
    foreach (var et in mb.Model.GetEntityTypes().Where(e => e.GetContainer() == container))
    {
        // re-declare the same partition key shape on every type
    }
}

Prevention

When it happens

Trigger: EntityA declares HasPartitionKey(a => a.TenantId) and EntityB (same container) declares no partition key or two; sharing a container between entity types via HasContainerName without aligning partition keys; one entity in a discriminator-shared container has a composite partition key while others have a single key.

Common situations: Sharing containers between unrelated entity types for cost/throughput reasons without normalizing partition keys; partial configuration where some types set partition keys and others rely on defaults; discriminator-based multi-type containers where partition key was configured on only some types.

Related errors


AI-assisted analysis of dotnet/efcore@3a2006ef56 (2026-08-11). Data as JSON: /api/errors/bc76b2d9ded00a7e. Report an issue: GitHub.

Appendix: source

Thrown at src/EFCore.Cosmos/Infrastructure/Internal/CosmosModelValidator.cs:166

        foreach (var entityType in mappedTypes)
        {
            Check.DebugAssert(entityType.IsDocumentRoot(), "Only document roots expected here.");

            var storeNames = entityType.GetPartitionKeyPropertyNames()
                .Select(n => entityType.FindProperty(n)?.GetJsonPropertyName())
                .ToList();

            if (firstEntityType is null)
            {
                partitionKeyStoreNames = storeNames;
                firstEntityType = entityType;
            }
            else
            {
                if (partitionKeyStoreNames.Count != storeNames.Count)
                {
                    throw new InvalidOperationException(
                        CosmosStrings.NoPartitionKey(
                            firstEntityType.DisplayName(),
                            string.Join(",", partitionKeyStoreNames),
                            entityType.DisplayName(),
                            string.Join(",", storeNames),
                            container));
                }

                for (var i = 0; i < storeNames.Count; i++)
                {
                    if (!string.Equals(storeNames[i], partitionKeyStoreNames[i], StringComparison.Ordinal))
                    {
                        throw new InvalidOperationException(
                            CosmosStrings.PartitionKeyStoreNameMismatch(
                                firstEntityType.GetPartitionKeyPropertyNames()[i],
                                firstEntityType.DisplayName(),
                                partitionKeyStoreNames[i],
                                entityType.GetPartitionKeyPropertyNames()[i],

View on GitHub (pinned to 3a2006ef56)