{"record":{"id":"a5776418f61db69c","repo":"dotnet/efcore","slug":"hasshadowid-was-called-on-a-non-root-entity-type","errorCode":null,"errorMessage":"'HasShadowId' was called on a non-root entity type '{entityType}'. JSON 'id' configuration can only be made on the document root.","messagePattern":"'HasShadowId' was called on a non-root entity type '(.+?)'\\. JSON 'id' configuration can only be made on the document root\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/EFCore.Cosmos/Infrastructure/Internal/CosmosModelValidator.cs","lineNumber":565,"sourceCode":"    ///     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\n    ///     any release. You should only use it directly in your code with extreme caution and knowing that\n    ///     doing so can result in application failures when updating to a new Entity Framework Core release.\n    /// </summary>\n    protected virtual void ValidateDiscriminatorMappings(\n        IEntityType entityType,\n        IDiagnosticsLogger<DbLoggerCategory.Model.Validation> logger)\n    {\n        if (!entityType.IsDocumentRoot()\n            && entityType.FindAnnotation(CosmosAnnotationNames.DiscriminatorInKey) != null)\n        {\n            throw new InvalidOperationException(CosmosStrings.DiscriminatorInKeyOnNonRoot(entityType.DisplayName()));\n        }\n\n        if (!entityType.IsDocumentRoot()\n            && entityType.FindAnnotation(CosmosAnnotationNames.HasShadowId) != null)\n        {\n            throw new InvalidOperationException(CosmosStrings.HasShadowIdOnNonRoot(entityType.DisplayName()));\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\n    ///     any release. You should only use it directly in your code with extreme caution and knowing that\n    ///     doing so can result in application failures when updating to a new Entity Framework Core release.\n    /// </summary>\n    protected override void ValidateIndex(\n        IIndex index,\n        IDiagnosticsLogger<DbLoggerCategory.Model.Validation> logger)\n    {\n        base.ValidateIndex(index, logger);\n\n        if (index.GetVectorIndexType() != null)\n        {\n            ValidateVectorIndex(index, logger);","sourceCodeStart":547,"sourceCodeEnd":583,"githubUrl":"https://github.com/dotnet/efcore/blob/3a2006ef569de08368d59db5e1468aa8f407e4f8/src/EFCore.Cosmos/Infrastructure/Internal/CosmosModelValidator.cs#L547-L583","documentation":"Thrown when HasShadowId is configured on a non-root entity type. The shadow-id flag tells EF to manage a shadow 'id' property, which is a document-root concern because the 'id' field belongs to the whole document. The validator detects the HasShadowId annotation on any type where IsDocumentRoot() is false and throws.","triggerScenarios":"Calling HasShadowId() on a derived entity (one with a BaseType). Fires during ValidateDiscriminatorMappings.","commonSituations":"Applying HasShadowId inside a per-derived-type configuration; copying a root configuration onto a derived type; misunderstanding that shadow id is a per-document (root) concern.","solutions":["Move the HasShadowId call to the document-root entity type.","If using IEntityTypeConfiguration<T>, only invoke it on the root.","Remove the call from derived types; the root manages the shadow id for the hierarchy."],"exampleFix":"// before\nmodelBuilder.Entity<DerivedOrder>().HasShadowId();\n\n// after\nmodelBuilder.Entity<Order>().HasShadowId();","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"static bool IsDocumentRoot(Type t, IModel model)\n    => model.FindEntityType(t)?.IsDocumentRoot() ?? false;\n\nif (IsDocumentRoot(typeof(Order), modelBuilder.Model))\n    modelBuilder.Entity<Order>().HasShadowId();","tryCatchPattern":null,"preventionTips":["Call HasShadowId only on the document root.","Keep shadow-id configuration in a root-only IEntityTypeConfiguration.","Add a unit test asserting no derived type carries the HasShadowId annotation."],"tags":["cosmos","model-validation","shadow-id","json-id","hierarchy","configuration"],"backgroundTag":null,"analyzedSha":"3a2006ef569de08368d59db5e1468aa8f407e4f8","analyzedAt":"2026-08-11T23:42:04.146Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}