{"record":{"id":"652774e1349f7556","repo":"dotnet/efcore","slug":"the-partition-key-value-is-of-type-valuetype-w","errorCode":null,"errorMessage":"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.","messagePattern":"The partition key value is of type '(.+?)' 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\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/EFCore.Cosmos/Extensions/Internal/PartitionKeyBuilderExtensions.cs","lineNumber":78,"sourceCode":"                    if (expectedType != null && expectedType != typeof(bool))\n                    {\n                        CheckType(typeof(bool));\n                    }\n\n                    builder.Add(boolValue);\n                    break;\n\n                case var _ when value.GetType().IsNumeric():\n                    if (expectedType != null && !expectedType.IsNumeric())\n                    {\n                        CheckType(value.GetType());\n                    }\n\n                    builder.Add(Convert.ToDouble(value));\n                    break;\n\n                default:\n                    throw new InvalidOperationException(CosmosStrings.PartitionKeyBadValue(value.GetType()));\n            }\n\n            void CheckType(Type actualType)\n            {\n                if (expectedType != null && expectedType != actualType)\n                {\n                    throw new InvalidOperationException(\n                        CosmosStrings.PartitionKeyBadValueType(\n                            expectedType.ShortDisplayName(),\n                            property!.DeclaringType.DisplayName(),\n                            property.Name,\n                            actualType.DisplayName()));\n                }\n            }\n        }\n\n        return builder;\n    }","sourceCodeStart":60,"sourceCodeEnd":96,"githubUrl":"https://github.com/dotnet/efcore/blob/dbf9771522148d61a2467854921bd5dc6f6e6916/src/EFCore.Cosmos/Extensions/Internal/PartitionKeyBuilderExtensions.cs#L60-L96","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["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.","Convert the value before passing it to WithPartitionKey (e.g. guid.ToString()).","Re-declare the partition key property with a Cosmos-supported CLR type."],"exampleFix":"// before (Guid partition key, unsupported type)\nmodelBuilder.Entity<Item>()\n    .HasPartitionKey(i => i.TenantId) // TenantId is Guid\n    .PartitionKey(e => e.TenantId);\nvar q = context.Items.WithPartitionKey(tenantGuid);\n\n// after (convert Guid to string at the store)\nmodelBuilder.Entity<Item>(b =>\n{\n    b.HasPartitionKey(i => i.TenantId);\n    b.Property(i => i.TenantId).HasConversion(g => g.ToString(), s => Guid.Parse(s));\n});\nvar q = context.Items.WithPartitionKey(tenantGuid.ToString());","handlingStrategy":"validation","validationCode":"// Validate partition key value type before use.\nstatic bool IsSupportedPartitionKeyType(object? value) => value switch\n{\n    null => true,\n    string or bool => true,\n    _ when value.GetType().IsNumeric() => true,\n    _ => false,\n};\nif (!IsSupportedPartitionKeyType(value))\n    throw new ArgumentException($\"Unsupported partition key type {value?.GetType()}.\");\nreturn context.Items.WithPartitionKey(value);","typeGuard":"static bool IsValidPartitionValue(object? v) =>\n    v is null || v is string || v is bool || v.GetType().IsNumeric();","tryCatchPattern":"try { return context.Items.WithPartitionKey(value).ToList(); }\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"partition key\"))\n{ throw new ArgumentException(\"Use a string/bool/numeric partition key, or add a value converter.\", ex); }","preventionTips":["Use string/bool/numeric partition key properties, or add HasConversion to one of those types.","Avoid Guid/DateTime/enum partition keys without a value converter.","Convert values (e.g. Guid.ToString()) before passing to WithPartitionKey."],"tags":["cosmos","partition-key","type-mapping","value-conversion"],"analyzedSha":"dbf9771522148d61a2467854921bd5dc6f6e6916","analyzedAt":"2026-08-06T20:46:03.226Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}