dotnet/efcore · error · InvalidOperationException
The type of the partition key property
Error message
The type of the partition key property '{property}' on '{entityType}' is '{propertyType}'. All partition key property types must be numeric, Boolean, or string, or converted to one of these types. What it means
Thrown when a partition key property's effective store type is not string, numeric, or Boolean. Cosmos partition keys must be one of those primitive types (or a value converter to one of them). The validator unwrapping-nullable on the converter's ProviderClrType (or ClrType) and rejects anything else (e.g. Guid, DateTimeOffset, byte[]).
Solutions
- Add a value converter that maps the property to string or a numeric type: .HasConversion<string>() (most common) or .HasConversion<long>().
- Choose a different partition-key property that is already string/numeric/bool.
- For enums, use HasConversion<int>() or HasConversion<string>().
- For Guids, HasConversion<string>() is the typical fix.
Example fix
// before
modelBuilder.Entity<Event>().HasPartitionKey(e => e.EventId); // Guid
// after
modelBuilder.Entity<Event>()
.Property(e => e.EventId).HasConversion<string>();
modelBuilder.Entity<Event>().HasPartitionKey(e => e.EventId); Defensive patterns
Strategy: validation
Validate before calling
foreach (var et in dbContext.Model.GetEntityTypes())
{
foreach (var name in et.GetPartitionKeyPropertyNames())
{
var p = et.FindProperty(name);
if (p is null) continue;
var t = (p.GetTypeMapping().Converter?.ProviderClrType ?? p.ClrType).UnwrapNullableType();
if (t != typeof(string) && !t.IsNumeric() && t != typeof(bool))
throw new InvalidOperationException($"{name} partition key type {t} not allowed");
}
} Prevention
- Convert Guid/Date/enum partition key properties with HasConversion<string>() or HasConversion<int>().
- Prefer string or long for partition keys.
- Add a model-validation unit test asserting partition key store types.
When it happens
Trigger: Configuring HasPartitionKey on a property whose ClrType is Guid, DateTime, DateTimeOffset, byte[], enum (without conversion), or any custom struct, without a value converter to a numeric/string/bool type. Fires during ValidateKeys.
Common situations: Partitioning by a Guid id directly; partitioning by a DateTime column; using an enum as the partition key without a numeric/string converter; new partition key on a property whose type was chosen for business logic, not Cosmos compatibility.
Related errors
- A partition key is defined on entity type
- The partition key for entity type
- The type of the ' ' property on ' ' is ' '. All 'id'…
- A full-text index is defined for
- A full-text index on
AI-assisted analysis of dotnet/efcore@3a2006ef56 (2026-08-11).
Data as JSON: /api/errors/e65f3aafab352e1a.
Report an issue: GitHub.
Appendix: source
Thrown at src/EFCore.Cosmos/Infrastructure/Internal/CosmosModelValidator.cs:477
CosmosStrings.PartitionKeyNotOnRoot(entityType.DisplayName(), entityType.BaseType.DisplayName()));
}
foreach (var partitionKeyPropertyName in partitionKeyPropertyNames)
{
var partitionKey = entityType.FindProperty(partitionKeyPropertyName);
if (partitionKey == null)
{
throw new InvalidOperationException(
CosmosStrings.PartitionKeyMissingProperty(entityType.DisplayName(), partitionKeyPropertyName));
}
var partitionKeyType = (partitionKey.GetTypeMapping().Converter?.ProviderClrType
?? partitionKey.ClrType).UnwrapNullableType();
if (partitionKeyType != typeof(string)
&& !partitionKeyType.IsNumeric()
&& partitionKeyType != typeof(bool))
{
throw new InvalidOperationException(
CosmosStrings.PartitionKeyBadStoreType(
partitionKeyPropertyName,
entityType.DisplayName(),
partitionKeyType.ShortDisplayName()));
}
}
}
}
/// <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)
{View on GitHub (pinned to 3a2006ef56)