{"record":{"id":"723c191c9b1b5d36","repo":"dotnet/efcore","slug":"the-partition-key-value-supplied-for-propertytyp","errorCode":null,"errorMessage":"The partition key value supplied for '{propertyType}' property '{entityType}.{property}' is of type '{valueType}'. Partition key values must be of a type assignable to the property.","messagePattern":"The partition key value supplied for '(.+?)' property '(.+?)\\.(.+?)' is of type '(.+?)'\\. Partition key values must be of a type assignable to the property\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/EFCore.Cosmos/Extensions/Internal/PartitionKeyBuilderExtensions.cs","lineNumber":85,"sourceCode":"\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    }\n}\n","sourceCodeStart":67,"sourceCodeEnd":98,"githubUrl":"https://github.com/dotnet/efcore/blob/3a2006ef569de08368d59db5e1468aa8f407e4f8/src/EFCore.Cosmos/Extensions/Internal/PartitionKeyBuilderExtensions.cs#L67-L98","documentation":"The nested CheckType in PartitionKeyBuilderExtensions.Add throws InvalidOperationException(CosmosStrings.PartitionKeyBadValueType) when the value's runtime type matches one of the supported primitive categories (string/bool/numeric) but does not match the expectedType derived from the property's converter or ClrType. For example, the property is declared as bool but the value supplied is a string, or the property is a string but the value is a double.","triggerScenarios":"Supplying a string value for a bool partition key property; supplying a double for an int partition key property when the converter expects int; supplying a numeric value where the property type is string; mixing types when building a multi-value partition key with values from loosely typed sources (e.g. deserialized JSON where everything is string).","commonSituations":"Reading partition key values from JSON/HTTP where they arrive as strings but the property is numeric or bool; mismatched conventions between producer and consumer of partition key values; partial migration where one side treats the key as int and the other as long.","solutions":["Convert the value to the property's exact ClrType (or its converter's ProviderClrType) before calling Add - use Convert.ChangeType or an explicit cast.","Make the producer and consumer agree on the partition key's primitive type; do not send strings where ints are expected.","If you genuinely need flexibility, configure a value converter that accepts the incoming type and converts to the property type.","Validate expectedType against value.GetType() before calling Add and surface a domain-level error rather than hitting the EF exception."],"exampleFix":"// before - throws: property is int, value came in as string from JSON\nvar pk = JsonSerializer.Deserialize<JsonElement>(payload).GetProperty(\"pk\").GetString();\nbuilder.Add(pk, intPartitionKeyProperty);\n\n// after - convert to the property's type first\nvar pkString = JsonSerializer.Deserialize<JsonElement>(payload).GetProperty(\"pk\").GetString();\nbuilder.Add(int.Parse(pkString), intPartitionKeyProperty);","handlingStrategy":"validation","validationCode":"// Coerce the value to the property's exact type before calling Add.\nstatic object CoerceToPropertyType(object value, IProperty property)\n{\n    var expected = (property.GetTypeMapping().Converter?.ProviderClrType ?? property.ClrType).UnwrapNullableType();\n    var actual = value.GetType();\n    if (actual == expected) return value;\n    if (expected == typeof(string) && actual != typeof(string)) return Convert.ToString(value)!;\n    return Convert.ChangeType(value, expected);\n}\nbuilder.Add(CoerceToPropertyType(value, property), property);","typeGuard":"static bool MatchesPropertyType(object value, IProperty property)\n{\n    var expected = (property.GetTypeMapping().Converter?.ProviderClrType ?? property.ClrType).UnwrapNullableType();\n    return value.GetType() == expected;\n}","tryCatchPattern":null,"preventionTips":["Make the producer and consumer of partition key values agree on a primitive type.","Convert at the boundary - do not push JSON strings into int/bool partition keys.","Unit-test partition key building with values from every input source (HTTP, JSON, DB).","Log the expected vs actual type when validation fails for faster diagnosis."],"tags":["ef-core","cosmos","partition-key","type-conversion","validation"],"backgroundTag":null,"analyzedSha":"3a2006ef569de08368d59db5e1468aa8f407e4f8","analyzedAt":"2026-08-11T23:42:04.146Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}