{"record":{"id":"806f27eb8003891b","repo":"dotnet/efcore","slug":"the-entity-type-entitytype-does-not-have-a-pro-806f27","errorCode":null,"errorMessage":"The entity type '{entityType}' does not have a property mapped to the 'id' property in the database. Add a property mapped to 'id'.","messagePattern":"The entity type '(.+?)' does not have a property mapped to the 'id' property in the database\\. Add a property mapped to 'id'\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/EFCore.Cosmos/Storage/Internal/CosmosStructuralTypeSerializer.cs","lineNumber":84,"sourceCode":"        _ordinalKeyProperty = structuralType.GetProperties().SingleOrDefault(p => p.IsOrdinalKeyProperty());\n        _scalarProperties =\n        [\n            .. structuralType.GetProperties().Where(p => p.IsPersisted() && p != _discriminatorProperty?.Property).Select(p\n                => (p, p.GetJsonPropertyName(),\n                    p.GetJsonValueReaderWriter()\n                    ?? p.GetTypeMapping().JsonValueReaderWriter\n                    ?? throw new UnreachableException(\"Property without JsonValueReaderWriter\")))\n        ];\n        _complexProperties =\n            [.. structuralType.GetComplexProperties().Select(cp => (cp, cp.GetJsonPropertyName(), provider.Get(cp.ComplexType)))];\n\n        if (structuralType is IEntityType entityType)\n        {\n            if (entityType.IsDocumentRoot())\n            {\n                _jsonIdProperty = structuralType.GetProperties()\n                        .FirstOrDefault(p => p.GetJsonPropertyName() == CosmosJsonIdConvention.IdPropertyJsonName)\n                    ?? throw new InvalidOperationException(CosmosStrings.NoIdProperty(structuralType.DisplayName()));\n                _container = entityType.GetContainer()\n                    ?? throw new UnreachableException(\"Document root entity type does not have container.\");\n            }\n\n            _navigations =\n            [\n                .. entityType.GetNavigations().Where(n => n.ForeignKey.IsOwnership && !n.IsOnDependent).Select(n\n                    => (n,\n                        n.TargetEntityType.GetContainingPropertyName()\n                        ?? throw new UnreachableException(\"Owned entity without containing property name\"),\n                        provider.Get(n.TargetEntityType)))\n            ];\n        }\n    }\n\n    /// <summary>\n    ///     This is an internal API that supports the Entity Framework Core infrastructure and not subject to\n    ///     the same compatibility standards as public APIs. It may be changed or removed without notice in","sourceCodeStart":66,"sourceCodeEnd":102,"githubUrl":"https://github.com/dotnet/efcore/blob/dbf9771522148d61a2467854921bd5dc6f6e6916/src/EFCore.Cosmos/Storage/Internal/CosmosStructuralTypeSerializer.cs#L66-L102","documentation":"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'.","triggerScenarios":"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.","commonSituations":"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.","solutions":["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\").","Do not remove or rename the 'id' mapping convention for document-root entities.","Verify the property has HasJsonPropertyName(\"id\") or relies on the default convention that lowercases 'Id' to 'id'."],"exampleFix":"// before — entity with no id-mapped property\npublic class Widget\n{\n    public string WidgetKey { get; set; } // not mapped to 'id'\n}\n\n// after\npublic class Widget\n{\n    public string Id { get; set; } = null!; // convention maps to 'id'\n}\n// or explicit mapping\nmodelBuilder.Entity<Widget>()\n    .Property(w => w.WidgetKey)\n    .ToJsonProperty(\"id\");","handlingStrategy":"validation","validationCode":"// After model finalization, verify every document-root entity has a property mapped to 'id'.\nforeach (var entityType in model.GetEntityTypes().Where(et => et.IsDocumentRoot()))\n{\n    var hasId = entityType.GetProperties().Any(p => p.GetJsonPropertyName() == \"id\");\n    if (!hasId)\n        throw new InvalidOperationException($\"{entityType.DisplayName()} has no property mapped to 'id'.\");\n}","typeGuard":"// Guard: confirm an entity type has an id-mapped property\nstatic bool HasIdProperty(IEntityType entityType)\n    => entityType.GetProperties().Any(p => p.GetJsonPropertyName() == \"id\");","tryCatchPattern":null,"preventionTips":["Give every document-root entity a property named 'Id' (convention maps it to JSON 'id').","Do not override ToJsonProperty() on the key to a non-'id' value.","Add a model-validation test asserting document-root entities have an 'id' property."],"tags":["cosmos","model-configuration","document-id","serialization"],"analyzedSha":"dbf9771522148d61a2467854921bd5dc6f6e6916","analyzedAt":"2026-08-06T20:46:03.226Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}