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
- Remove the .Except(...) call when HasAutomaticIndexing(false) is set (with auto-indexing off, paths are excluded by default).
- If you want selective indexing, call HasAutomaticIndexing(true) and then chain .Except(path) for each path to exclude.
- 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
- Remember the indexing direction: when auto-indexing is OFF you add included paths; when ON you add excluded paths via Except.
- Keep the indexing-policy chain together and read it as a unit.
- Add a fluent helper that picks Except vs IncludedPath based on the enabled flag.
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
- Cosmos automatic-indexing configuration was set on entity…
- Cosmos automatic indexing is enabled for some entity types…
- The exception list configured for Cosmos automatic indexing…
- The index over properties
- A call was made to ' ' that changed an option that must be…
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 byView on GitHub (pinned to 3a2006ef56)