dotnet/efcore · error · InvalidOperationException

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

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. Path exceptions only have meaning while automatic indexing is on, so calling Except() on a builder produced by HasAutomaticIndexing(false) is rejected immediately.

Solutions

  1. Remove the .Except(...) call when HasAutomaticIndexing(false) is set (with auto-indexing off, paths are excluded by default).
  2. If you want selective indexing, call HasAutomaticIndexing(true) and then chain .Except(path) for each path to exclude.
  3. Re-read your indexing policy: when auto-indexing is off you opt paths IN, not OUT.

Example fix

// before
modelBuilder.Entity<Doc>()
    .HasAutomaticIndexing(false)
    .Except("/temp/*");

// after - choose one
// (a) auto-indexing off: drop Except
modelBuilder.Entity<Doc>().HasAutomaticIndexing(false);
// (b) auto-indexing on with exceptions
modelBuilder.Entity<Doc>()
    .HasAutomaticIndexing(true)
    .Except("/temp/*");
Defensive patterns

Strategy: type-guard

Validate before calling

// Before chaining Except, check the current setting.
var meta = modelBuilder.Entity<Doc>().Metadata;
if (meta.GetAutomaticIndexingEnabled() == false)
    throw new InvalidOperationException("Cannot call Except() when automatic indexing is disabled.");

Prevention

When it happens

Trigger: Calling modelBuilder.Entity<T>().HasAutomaticIndexing(false).Except("/some/path") in one chain.

Common situations: Turning off automatic indexing and then trying to carve out exception paths in the same fluent chain; copy-pasting indexing-policy code from an enabled configuration into a disabled one.

Related errors


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

Appendix: 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 3a2006ef56)