dotnet/efcore · error · InvalidOperationException

The type of the ' ' property on ' ' is ' '. All 'id'…

Error message

The type of the '{idProperty}' property on '{entityType}' is '{propertyType}'. All 'id' properties must be strings or have a string value converter.

What it means

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.

Solutions

  1. Add a string value converter to the id-mapped property: .HasConversion<string>() (or a custom converter that returns a string).
  2. If the property is a Guid/int/long, HasConversion<string>() is the canonical fix.
  3. Confirm the type mapping's ProviderClrType is string - a converter to any other type will still fail.
  4. Reassign the 'id' JSON mapping to a different property that is already a string.

Example fix

// before
modelBuilder.Entity<User>()
    .Property(u => u.Id)               // Guid
    .ToJsonProperty("id");

// after
modelBuilder.Entity<User>()
    .Property(u => u.Id)
    .HasConversion<string>()
    .ToJsonProperty("id");
Defensive patterns

Strategy: validation

Validate before calling

foreach (var et in dbContext.Model.GetEntityTypes().Where(e => e.IsDocumentRoot()))
{
    var id = et.GetProperties().FirstOrDefault(p => p.GetJsonPropertyName() == CosmosJsonIdConvention.IdPropertyJsonName);
    if (id is null) continue;
    var storeType = id.GetTypeMapping().Converter?.ProviderClrType ?? id.ClrType;
    if (storeType != typeof(string)) throw new InvalidOperationException($"{id.Name} id store type is {storeType}");
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of dotnet/efcore@3a2006ef56 (2026-08-11). Data as JSON: /api/errors/da79aa0404e3a505. Report an issue: GitHub.

Appendix: source

Thrown at src/EFCore.Cosmos/Infrastructure/Internal/CosmosModelValidator.cs:444

        var primaryKey = entityType.FindPrimaryKey();
        if (primaryKey == null
            || !entityType.IsDocumentRoot())
        {
            return;
        }

        var idProperty = entityType.GetProperties()
            .FirstOrDefault(p => p.GetJsonPropertyName() == CosmosJsonIdConvention.IdPropertyJsonName);
        if (idProperty == null)
        {
            throw new InvalidOperationException(CosmosStrings.NoIdProperty(entityType.DisplayName()));
        }

        var idType = idProperty.GetTypeMapping().Converter?.ProviderClrType
            ?? idProperty.ClrType;
        if (idType != typeof(string))
        {
            throw new InvalidOperationException(
                CosmosStrings.IdNonStringStoreType(idProperty.Name, entityType.DisplayName(), idType.ShortDisplayName()));
        }

        var partitionKeyPropertyNames = entityType.GetPartitionKeyPropertyNames();
        if (partitionKeyPropertyNames.Count == 0)
        {
            logger.NoPartitionKeyDefined(entityType);
        }
        else
        {
            if (entityType.BaseType != null
                && entityType.FindAnnotation(CosmosAnnotationNames.PartitionKeyNames)?.Value != null)
            {
                throw new InvalidOperationException(
                    CosmosStrings.PartitionKeyNotOnRoot(entityType.DisplayName(), entityType.BaseType.DisplayName()));
            }

            foreach (var partitionKeyPropertyName in partitionKeyPropertyNames)

View on GitHub (pinned to 3a2006ef56)