dotnet/efcore · error · InvalidOperationException

The entity type '{entityType}' does not have a property mapp

Error message

The entity type '{entityType}' does not have a property mapped to the 'id' property in the database. Add a property mapped to 'id'.

What it means

Every document-root entity in Cosmos DB must have a property that maps to the JSON 'id' field, which Cosmos uses as the document's resource identifier. During serializer construction (CosmosStructuralTypeSerializer.cs:82-84), EF Core looks for a property whose GetJsonPropertyName() equals 'id' (the CosmosJsonIdConvention.IdPropertyJsonName). If none is found, the entity cannot be persisted because Cosmos requires an 'id'.

Source

Thrown at src/EFCore.Cosmos/Storage/Internal/CosmosStructuralTypeSerializer.cs:84

        _ordinalKeyProperty = structuralType.GetProperties().SingleOrDefault(p => p.IsOrdinalKeyProperty());
        _scalarProperties =
        [
            .. structuralType.GetProperties().Where(p => p.IsPersisted() && p != _discriminatorProperty?.Property).Select(p
                => (p, p.GetJsonPropertyName(),
                    p.GetJsonValueReaderWriter()
                    ?? p.GetTypeMapping().JsonValueReaderWriter
                    ?? throw new UnreachableException("Property without JsonValueReaderWriter")))
        ];
        _complexProperties =
            [.. structuralType.GetComplexProperties().Select(cp => (cp, cp.GetJsonPropertyName(), provider.Get(cp.ComplexType)))];

        if (structuralType is IEntityType entityType)
        {
            if (entityType.IsDocumentRoot())
            {
                _jsonIdProperty = structuralType.GetProperties()
                        .FirstOrDefault(p => p.GetJsonPropertyName() == CosmosJsonIdConvention.IdPropertyJsonName)
                    ?? throw new InvalidOperationException(CosmosStrings.NoIdProperty(structuralType.DisplayName()));
                _container = entityType.GetContainer()
                    ?? throw new UnreachableException("Document root entity type does not have container.");
            }

            _navigations =
            [
                .. entityType.GetNavigations().Where(n => n.ForeignKey.IsOwnership && !n.IsOnDependent).Select(n
                    => (n,
                        n.TargetEntityType.GetContainingPropertyName()
                        ?? throw new UnreachableException("Owned entity without containing property name"),
                        provider.Get(n.TargetEntityType)))
            ];
        }
    }

    /// <summary>
    ///     This is an internal API that supports the Entity Framework Core infrastructure and not subject to
    ///     the same compatibility standards as public APIs. It may be changed or removed without notice in

View on GitHub (pinned to dbf9771522)

Solutions

  1. Ensure the entity has a property that maps to JSON 'id'. By convention, a property named 'Id' or '<EntityName>Id' maps to 'id'. If you customized the JSON name, set it explicitly: modelBuilder.Entity<T>().Property(x => x.Key).ToJsonProperty("id").
  2. Do not remove or rename the 'id' mapping convention for document-root entities.
  3. Verify the property has HasJsonPropertyName("id") or relies on the default convention that lowercases 'Id' to 'id'.

Example fix

// before — entity with no id-mapped property
public class Widget
{
    public string WidgetKey { get; set; } // not mapped to 'id'
}

// after
public class Widget
{
    public string Id { get; set; } = null!; // convention maps to 'id'
}
// or explicit mapping
modelBuilder.Entity<Widget>()
    .Property(w => w.WidgetKey)
    .ToJsonProperty("id");
Defensive patterns

Strategy: validation

Validate before calling

// After model finalization, verify every document-root entity has a property mapped to 'id'.
foreach (var entityType in model.GetEntityTypes().Where(et => et.IsDocumentRoot()))
{
    var hasId = entityType.GetProperties().Any(p => p.GetJsonPropertyName() == "id");
    if (!hasId)
        throw new InvalidOperationException($"{entityType.DisplayName()} has no property mapped to 'id'.");
}

Type guard

// Guard: confirm an entity type has an id-mapped property
static bool HasIdProperty(IEntityType entityType)
    => entityType.GetProperties().Any(p => p.GetJsonPropertyName() == "id");

Prevention

When it happens

Trigger: Defining a document-root entity type (mapped to a container, not embedded) that has no property named 'id' or configured to map to 'id'. This fires at model finalization/first use when the CosmosStructuralTypeSerializer is constructed for the entity type.

Common situations: Naming the key property 'Id' but with a ToJson camelCase or different JSON name that doesn't resolve to 'id'. Removing the default 'id' property convention. Using a key property with a custom JSON property name that is not 'id'. Mapping an entity to a container without a usable id property.

Related errors


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