dotnet/efcore · error · InvalidOperationException

The exception list configured for Cosmos automatic indexing…

Error message

The exception list configured for Cosmos automatic indexing on container '{container}' differs between entity types '{entityType1}' and '{entityType2}'. All entity types mapped to the same container must agree on the automatic-indexing exception list.

What it means

Thrown when the exception list for Cosmos automatic indexing differs between two entity types in the same container. The validator only compares exception lists when automatic indexing is enabled (since exceptions have no effect when indexing is off); it treats a null list as distinct from a non-null list and compares non-null lists with an ordinal SequenceEqual. All types sharing a container must declare the same exception list.

Solutions

  1. Collect every JSON path that must be excluded from indexing and pass the exact same list (same items, same order) to HasAutomaticIndexingExceptions on every document-root entity in the container.
  2. Centralize the exception list in a shared readonly field/property so all configs reference one source of truth.
  3. Remove partial HasAutomaticIndexingExceptions calls; either every root has the same list or none does.

Example fix

// before
modelBuilder.Entity<Invoice>().ToContainer("Docs")
    .HasAutomaticIndexing(true)
    .HasAutomaticIndexingExceptions("/Transient/*");
modelBuilder.Entity<Receipt>().ToContainer("Docs")
    .HasAutomaticIndexing(true)
    .HasAutomaticIndexingExceptions("/Cache/*");

// after
static readonly string[] Excluded = { "/Transient/*", "/Cache/*" };
modelBuilder.Entity<Invoice>().ToContainer("Docs")
    .HasAutomaticIndexing(true).HasAutomaticIndexingExceptions(Excluded);
modelBuilder.Entity<Receipt>().ToContainer("Docs")
    .HasAutomaticIndexing(true).HasAutomaticIndexingExceptions(Excluded);
Defensive patterns

Strategy: validation

Validate before calling

foreach (var g in dbContext.Model.GetEntityTypes().GroupBy(e => e.GetContainer()))
{
    IReadOnlyList<string>? first = null;
    foreach (var e in g.Where(et => et.BaseType is null))
    {
        var ex = e.FindAnnotation(CosmosAnnotationNames.AutomaticIndexingExceptions)?.Value as IReadOnlyList<string>;
        if (ex is null) continue;
        if (first is null) first = ex;
        else if (!first.SequenceEqual(ex, StringComparer.Ordinal))
            throw new InvalidOperationException($"Exception list mismatch on {g.Key}");
    }
}

Prevention

When it happens

Trigger: Two document-root entity types in the same container both enable automatic indexing but pass different paths to HasAutomaticIndexingExceptions, or one passes a list while the other passes none. Fires during model validation.

Common situations: Adding an excluded path to one root entity type and forgetting the others in the shared container; ordering differences in the exception list (compared with StringComparer.Ordinal, so order matters); refactoring JSON property paths that left stale exceptions on some types.

Related errors


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

Appendix: source

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

                    // an explicit 'true' when comparing across entity types in the same container.
                    if ((currentEnabled ?? true) != (automaticIndexingEnabled ?? true))
                    {
                        throw new InvalidOperationException(
                            CosmosStrings.InconsistentAutomaticIndexingEnabled(
                                container,
                                automaticIndexingOwner.DisplayName(),
                                entityType.DisplayName()));
                    }

                    // Exceptions only affect the indexing policy when automatic indexing is enabled, so don't compare
                    // them when it is disabled.
                    if ((automaticIndexingEnabled ?? true)
                        && ((currentExceptions is null) != (automaticIndexingExceptions is null)
                            || (currentExceptions is not null
                                && automaticIndexingExceptions is not null
                                && !currentExceptions.SequenceEqual(automaticIndexingExceptions, StringComparer.Ordinal))))
                    {
                        throw new InvalidOperationException(
                            CosmosStrings.InconsistentAutomaticIndexing(
                                container,
                                automaticIndexingOwner.DisplayName(),
                                entityType.DisplayName()));
                    }
                }
            }

            // Walk the full owned/complex tree to surface every HasIndex declared in this container.
            // Vector and full-text indexes are allowed to traverse owned types; only regular indexes are
            // rejected
            foreach (var (declaringEntityType, index) in EnumerateContainerIndexes(entityType))
            {
                if (!declaringEntityType.IsDocumentRoot()
                    && index.GetVectorIndexType() == null
                    && index.IsFullTextIndex() != true)
                {
                    throw new InvalidOperationException(

View on GitHub (pinned to 3a2006ef56)