dotnet/efcore · error · InvalidOperationException

'Except' cannot be called on the builder returned by 'HasAut

Error message

'Except' cannot be called on the builder returned by 'HasAutomaticIndexing(false)' because exceptions only apply when automatic indexing is enabled.

What it means

Thrown by CosmosAutomaticIndexingBuilder.Except when EntityTypeBuilder.Metadata.GetAutomaticIndexingEnabled() == false. Excluded paths (Cosmos indexing policy ExcludedPaths) only have meaning when automatic indexing is on; calling Except after HasAutomaticIndexing(false) is contradictory, so EF rejects it.

Source

Thrown at src/EFCore.Cosmos/Metadata/Builders/CosmosAutomaticIndexingBuilder.cs:57

    /// <summary>
    ///     Adds a path to the container's <c>ExcludedPaths</c>. The path must use Cosmos indexing-policy syntax
    ///     (e.g., <c>/secret/?</c> for a leaf, <c>/items/[]/*</c> for an array sub-tree). Throws if automatic
    ///     indexing was disabled via <c>HasAutomaticIndexing(false)</c>.
    /// </summary>
    /// <remarks>
    ///     See <see href="https://learn.microsoft.com/azure/cosmos-db/index-policy">Indexing policies in Azure Cosmos DB</see>
    ///     for more information.
    /// </remarks>
    /// <param name="path">The path to exclude from indexing.</param>
    /// <returns>The same builder instance so that multiple calls can be chained.</returns>
    public virtual CosmosAutomaticIndexingBuilder Except(string path)
    {
        Check.NotEmpty(path);

        if (EntityTypeBuilder.Metadata.GetAutomaticIndexingEnabled() == false)
        {
            throw new InvalidOperationException(CosmosStrings.AutomaticIndexingExceptionWhileDisabled);
        }

        var current = EntityTypeBuilder.Metadata.GetAutomaticIndexingExceptions();
        var updated = new List<string>((current?.Count ?? 0) + 1);
        if (current is not null)
        {
            updated.AddRange(current);
        }

        updated.Add(path);
        EntityTypeBuilder.Metadata.SetAutomaticIndexingExceptions(updated);

        return this;
    }
}

/// <summary>
///     A generic fluent builder used to configure the Cosmos container's automatic indexing policy. Returned by

View on GitHub (pinned to dbf9771522)

Solutions

  1. Remove the Except calls: if automatic indexing is disabled, nothing is indexed so exclusions are meaningless.
  2. If you actually want indexing on but with exclusions, switch to HasAutomaticIndexing(true) (or omit the flag) and keep the Except calls.

Example fix

// before
modelBuilder.Entity<Doc>()
    .HasAutomaticIndexing(false)
    .Except("/secret/?");

// after (option A: keep indexing off, drop exclusions)
modelBuilder.Entity<Doc>().HasAutomaticIndexing(false);
// after (option B: keep exclusions, enable indexing)
modelBuilder.Entity<Doc>()
    .HasAutomaticIndexing(true)
    .Except("/secret/?");
Defensive patterns

Strategy: validation

Validate before calling

// Before calling Except, confirm automatic indexing is not disabled
if (entityType.GetAutomaticIndexingEnabled() == false)
{
    throw new InvalidOperationException("Cannot call Except: automatic indexing is disabled.");
}

Prevention

When it happens

Trigger: Chaining .HasAutomaticIndexing(false).Except("/secret/?") on an EntityTypeBuilder, or calling Except after a separate call that disabled automatic indexing on the same entity.

Common situations: Copy-pasting indexing configuration from a 'with exceptions' snippet onto an entity whose indexing was already disabled. Toggling HasAutomaticIndexing off during troubleshooting but leaving Except calls in place.

Related errors


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