dotnet/efcore · error · InvalidOperationException

The partition key value is of type '{valueType}' which is no

Error message

The partition key value is of type '{valueType}' which is not valid for Cosmos partition keys. All partition key properties values must be numeric, Boolean, or string, or converted to one of these types.

What it means

The internal PartitionKeyBuilderExtensions.Add only accepts string, bool, or numeric partition key values. Any other CLR type reaches the default case and throws InvalidOperationException via CosmosStrings.PartitionKeyBadValue. Cosmos partition keys are restricted to number, boolean, or string at the store level.

Source

Thrown at src/EFCore.Cosmos/Extensions/Internal/PartitionKeyBuilderExtensions.cs:78

                    if (expectedType != null && expectedType != typeof(bool))
                    {
                        CheckType(typeof(bool));
                    }

                    builder.Add(boolValue);
                    break;

                case var _ when value.GetType().IsNumeric():
                    if (expectedType != null && !expectedType.IsNumeric())
                    {
                        CheckType(value.GetType());
                    }

                    builder.Add(Convert.ToDouble(value));
                    break;

                default:
                    throw new InvalidOperationException(CosmosStrings.PartitionKeyBadValue(value.GetType()));
            }

            void CheckType(Type actualType)
            {
                if (expectedType != null && expectedType != actualType)
                {
                    throw new InvalidOperationException(
                        CosmosStrings.PartitionKeyBadValueType(
                            expectedType.ShortDisplayName(),
                            property!.DeclaringType.DisplayName(),
                            property.Name,
                            actualType.DisplayName()));
                }
            }
        }

        return builder;
    }

View on GitHub (pinned to dbf9771522)

Solutions

  1. Use a string/bool/numeric property as the partition key, or configure a value converter (HasConversion) that maps the property to one of those store types.
  2. Convert the value before passing it to WithPartitionKey (e.g. guid.ToString()).
  3. Re-declare the partition key property with a Cosmos-supported CLR type.

Example fix

// before (Guid partition key, unsupported type)
modelBuilder.Entity<Item>()
    .HasPartitionKey(i => i.TenantId) // TenantId is Guid
    .PartitionKey(e => e.TenantId);
var q = context.Items.WithPartitionKey(tenantGuid);

// after (convert Guid to string at the store)
modelBuilder.Entity<Item>(b =>
{
    b.HasPartitionKey(i => i.TenantId);
    b.Property(i => i.TenantId).HasConversion(g => g.ToString(), s => Guid.Parse(s));
});
var q = context.Items.WithPartitionKey(tenantGuid.ToString());
Defensive patterns

Strategy: validation

Validate before calling

// Validate partition key value type before use.
static bool IsSupportedPartitionKeyType(object? value) => value switch
{
    null => true,
    string or bool => true,
    _ when value.GetType().IsNumeric() => true,
    _ => false,
};
if (!IsSupportedPartitionKeyType(value))
    throw new ArgumentException($"Unsupported partition key type {value?.GetType()}.");
return context.Items.WithPartitionKey(value);

Type guard

static bool IsValidPartitionValue(object? v) =>
    v is null || v is string || v is bool || v.GetType().IsNumeric();

Try / catch

try { return context.Items.WithPartitionKey(value).ToList(); }
catch (InvalidOperationException ex) when (ex.Message.Contains("partition key"))
{ throw new ArgumentException("Use a string/bool/numeric partition key, or add a value converter.", ex); }

Prevention

When it happens

Trigger: Passing a Guid, DateTime, DateTimeOffset, enum (without conversion), char, or arbitrary object as the partition key value through WithPartitionKey or the save path when the property is not value-converted to a supported primitive.

Common situations: Using a Guid id as the partition key directly; a DateTime tenant key with no value converter; an enum partition key without HasConversion; a struct/record partition key.

Related errors


AI-assisted analysis of dotnet/efcore@dbf9771522 (2026-08-06). Data as JSON: /api/errors/652774e1349f7556. Report an issue: GitHub.