{"record":{"id":"da79aa0404e3a505","repo":"dotnet/efcore","slug":"the-type-of-the-idproperty-property-on-entit","errorCode":null,"errorMessage":"The type of the '{idProperty}' property on '{entityType}' is '{propertyType}'. All 'id' properties must be strings or have a string value converter.","messagePattern":"The type of the '(.+?)' property on '(.+?)' is '(.+?)'\\. All 'id' properties must be strings or have a string value converter\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/EFCore.Cosmos/Infrastructure/Internal/CosmosModelValidator.cs","lineNumber":444,"sourceCode":"        var primaryKey = entityType.FindPrimaryKey();\n        if (primaryKey == null\n            || !entityType.IsDocumentRoot())\n        {\n            return;\n        }\n\n        var idProperty = entityType.GetProperties()\n            .FirstOrDefault(p => p.GetJsonPropertyName() == CosmosJsonIdConvention.IdPropertyJsonName);\n        if (idProperty == null)\n        {\n            throw new InvalidOperationException(CosmosStrings.NoIdProperty(entityType.DisplayName()));\n        }\n\n        var idType = idProperty.GetTypeMapping().Converter?.ProviderClrType\n            ?? idProperty.ClrType;\n        if (idType != typeof(string))\n        {\n            throw new InvalidOperationException(\n                CosmosStrings.IdNonStringStoreType(idProperty.Name, entityType.DisplayName(), idType.ShortDisplayName()));\n        }\n\n        var partitionKeyPropertyNames = entityType.GetPartitionKeyPropertyNames();\n        if (partitionKeyPropertyNames.Count == 0)\n        {\n            logger.NoPartitionKeyDefined(entityType);\n        }\n        else\n        {\n            if (entityType.BaseType != null\n                && entityType.FindAnnotation(CosmosAnnotationNames.PartitionKeyNames)?.Value != null)\n            {\n                throw new InvalidOperationException(\n                    CosmosStrings.PartitionKeyNotOnRoot(entityType.DisplayName(), entityType.BaseType.DisplayName()));\n            }\n\n            foreach (var partitionKeyPropertyName in partitionKeyPropertyNames)","sourceCodeStart":426,"sourceCodeEnd":462,"githubUrl":"https://github.com/dotnet/efcore/blob/3a2006ef569de08368d59db5e1468aa8f407e4f8/src/EFCore.Cosmos/Infrastructure/Internal/CosmosModelValidator.cs#L426-L462","documentation":"Thrown when the property mapped to the Cosmos JSON 'id' is not a string at the store level. The validator resolves the effective store type via the property's type mapping converter ProviderClrType (falling back to the ClrType) and requires it to be System.String. Cosmos stores 'id' as a string, so any non-string store type (with no converter to string) is invalid.","triggerScenarios":"An entity has a property mapped to the 'id' JSON name whose ClrType is int/Guid/byte[]/etc. and which has no value converter that produces a string at the provider level. Fires during ValidateKeys for document-root entity types.","commonSituations":"Using a Guid or int primary key directly as the id without a string conversion; mapping a byte[] token to 'id'; forgetting HasConversion<string>() after customizing the key; switching a key type and losing the converter.","solutions":["Add a string value converter to the id-mapped property: .HasConversion<string>() (or a custom converter that returns a string).","If the property is a Guid/int/long, HasConversion<string>() is the canonical fix.","Confirm the type mapping's ProviderClrType is string - a converter to any other type will still fail.","Reassign the 'id' JSON mapping to a different property that is already a string."],"exampleFix":"// before\nmodelBuilder.Entity<User>()\n    .Property(u => u.Id)               // Guid\n    .ToJsonProperty(\"id\");\n\n// after\nmodelBuilder.Entity<User>()\n    .Property(u => u.Id)\n    .HasConversion<string>()\n    .ToJsonProperty(\"id\");","handlingStrategy":"validation","validationCode":"foreach (var et in dbContext.Model.GetEntityTypes().Where(e => e.IsDocumentRoot()))\n{\n    var id = et.GetProperties().FirstOrDefault(p => p.GetJsonPropertyName() == CosmosJsonIdConvention.IdPropertyJsonName);\n    if (id is null) continue;\n    var storeType = id.GetTypeMapping().Converter?.ProviderClrType ?? id.ClrType;\n    if (storeType != typeof(string)) throw new InvalidOperationException($\"{id.Name} id store type is {storeType}\");\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always pair a non-string PK with HasConversion<string>().","Check the converter's ProviderClrType, not just ClrType.","Add a model-validation test asserting the id store type is string."],"tags":["cosmos","model-validation","id","type-conversion","configuration"],"backgroundTag":null,"analyzedSha":"3a2006ef569de08368d59db5e1468aa8f407e4f8","analyzedAt":"2026-08-11T23:42:04.146Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}