{"record":{"id":"f70bf47d9deb3249","repo":"dotnet/efcore","slug":"cosmos-automatic-indexing-configuration-was-set-on","errorCode":null,"errorMessage":"Cosmos automatic-indexing configuration was set on entity type '{entityType}', but it must be configured on the document-root entity type '{rootEntityType}' instead. Automatic-indexing settings apply to the container as a whole and are inherited by derived types.","messagePattern":"Cosmos automatic-indexing configuration was set on entity type '(.+?)', but it must be configured on the document-root entity type '(.+?)' instead\\. Automatic-indexing settings apply to the container as a whole and are inherited by derived types\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/EFCore.Cosmos/Infrastructure/Internal/CosmosModelValidator.cs","lineNumber":330,"sourceCode":"\n        ValidateContainerIndexing(mappedTypes, container);\n    }\n\n    private static void ValidateContainerIndexing(IReadOnlyList<IEntityType> mappedTypes, string container)\n    {\n        IEntityType? automaticIndexingOwner = null;\n        bool? automaticIndexingEnabled = null;\n        IReadOnlyList<string>? automaticIndexingExceptions = null;\n\n        foreach (var entityType in mappedTypes)\n        {\n            // Only document-root entity types can carry automatic-indexing configuration.\n            // The same setting must apply to every entity type in a shared container.\n            if (entityType.BaseType is not null\n                && (entityType.FindAnnotation(CosmosAnnotationNames.AutomaticIndexingEnabled) is not null\n                    || entityType.FindAnnotation(CosmosAnnotationNames.AutomaticIndexingExceptions) is not null))\n            {\n                throw new InvalidOperationException(\n                    CosmosStrings.AutomaticIndexingNotOnRoot(\n                        entityType.DisplayName(),\n                        entityType.GetRootType().DisplayName()));\n            }\n\n            var currentEnabled = entityType.BaseType is null\n                ? (bool?)entityType.FindAnnotation(CosmosAnnotationNames.AutomaticIndexingEnabled)?.Value\n                : null;\n            var currentExceptions = entityType.BaseType is null\n                ? (IReadOnlyList<string>?)entityType.FindAnnotation(CosmosAnnotationNames.AutomaticIndexingExceptions)?.Value\n                : null;\n            if (currentEnabled is not null || currentExceptions is not null)\n            {\n                if (automaticIndexingOwner is null)\n                {\n                    automaticIndexingOwner = entityType;\n                    automaticIndexingEnabled = currentEnabled;\n                    automaticIndexingExceptions = currentExceptions;","sourceCodeStart":312,"sourceCodeEnd":348,"githubUrl":"https://github.com/dotnet/efcore/blob/dbf9771522148d61a2467854921bd5dc6f6e6916/src/EFCore.Cosmos/Infrastructure/Internal/CosmosModelValidator.cs#L312-L348","documentation":"Thrown by ValidateContainerIndexing when a derived entity type (one whose BaseType is set) directly carries the AutomaticIndexingEnabled or AutomaticIndexingExceptions annotation. The validator explicitly checks these annotations on non-root types and rejects them, because automatic indexing is a container-wide policy that must live on the document root and is inherited by derived types.","triggerScenarios":"Calling HasAutomaticIndexing(...) (or chained .Except(...)) on an EntityTypeBuilder whose entity is a derived type in a TPH/inheritance hierarchy, during model validation.","commonSituations":"Applying a shared configuration routine to every entity in an inheritance hierarchy without skipping derived types; configuring indexing per-entity thinking it is per-type; recent upgrade that introduced container-level indexing config.","solutions":["Move the HasAutomaticIndexing call to the root entity type of the hierarchy.","Guard your shared configuration helper with `if (entityType.BaseType == null)` before applying automatic-indexing config.","Remove the call from the derived type and re-apply it on the root via the root's EntityTypeBuilder."],"exampleFix":"// before\nmodelBuilder.Entity<Manager>().HasAutomaticIndexing(true); // Manager derives from Employee\n\n// after\nmodelBuilder.Entity<Employee>().HasAutomaticIndexing(true); // applied on the root","handlingStrategy":"validation","validationCode":"// Guard your shared config helper so automatic indexing is only set on roots:\nstatic void ConfigureCosmos<T>(EntityTypeBuilder<T> et) where T : class\n{\n    if (et.Metadata.BaseType is null)\n        et.HasAutomaticIndexing(true);\n}\n// In a test:\nusing var ctx = new MyContext();\nforeach (var e in ctx.Model.GetEntityTypes().Where(t => t.BaseType is not null))\n{\n    Debug.Assert(e.FindAnnotation(\"Cosmos:AutomaticIndexingEnabled\") is null\n        && e.FindAnnotation(\"Cosmos:AutomaticIndexingExceptions\") is null,\n        $\"{e.Name} must not set automatic indexing (not a root)\");\n}","typeGuard":"// Type-guard-style helper: only apply container-level config to document roots.\nstatic bool IsDocumentRoot<TEntity>(EntityTypeBuilder<TEntity> et) where T : class\n    => et.Metadata.BaseType is null && et.Metadata.IsDocumentRoot();","tryCatchPattern":"try { ctx.Model.GetModel(); }\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"automatic-indexing configuration was set\"))\n{\n    logger.LogError(ex, \"HasAutomaticIndexing called on a derived type\");\n    throw;\n}","preventionTips":["Always check entityType.BaseType == null before applying container-level (indexing, partition key, TTL, throughput) config.","Prefer model-level / root-only configuration helpers in OnModelCreating.","Add a test asserting no derived type carries automatic-indexing annotations."],"tags":["cosmos","configuration","model-validation","indexing","inheritance"],"analyzedSha":"dbf9771522148d61a2467854921bd5dc6f6e6916","analyzedAt":"2026-08-06T20:46:03.226Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}