dotnet/efcore · error · InvalidOperationException

The index {indexProperties} on the entity type '{entityType}

Error message

The index {indexProperties} on the entity type '{entityType}' cannot be configured because its property '{property}' traverses a complex collection but is not mapped to a JSON column.

What it means

Thrown during index validation when an index property path traverses a complex collection (CollectionIndices[i] is non-null) but the property at that position is not inside a JSON-mapped column. EF can only create a JSON-path index over properties inside a JSON document column; a complex collection without JSON mapping produces no addressable single column. See RelationalModelValidator.cs:2713-2725 where container is null but CollectionIndices entry is non-null.

Source

Thrown at src/EFCore.Relational/Infrastructure/RelationalModelValidator.cs:2720

        {
            var property = index.Properties[i];

            // Only properties mapped inside a JSON container matter here. Mixed JSON / non-JSON indexes
            // are rejected earlier by ValidateIndexPropertyMapping.
            var container = property.DeclaringType is IReadOnlyComplexType complexType && complexType.IsMappedToJson()
                ? complexType.GetContainerColumnName()
                : property is IReadOnlyComplexProperty complexProperty && complexProperty.ComplexType.IsMappedToJson()
                    ? complexProperty.ComplexType.GetContainerColumnName()
                    : null;

            if (container is null)
            {
                // Not a JSON-contained property. If this position carries a non-null collection-indices
                // entry (i.e., the path traverses a complex collection but doesn't end in JSON), the
                // index identity points at a JSON path that has no JSON container — that's invalid.
                if (index.CollectionIndices?[i] is not null)
                {
                    throw new InvalidOperationException(
                        RelationalStrings.JsonPathIndexPropertyMissingJsonColumn(
                            index.Properties.Format(),
                            index.DeclaringEntityType.DisplayName(),
                            property.Name));
                }

                continue;
            }

            if (firstContainer is null)
            {
                firstContainer = container;
            }
            else if (!string.Equals(firstContainer, container, StringComparison.Ordinal))
            {
                throw new InvalidOperationException(
                    RelationalStrings.JsonPathIndexPropertiesInDifferentJsonColumns(
                        index.Properties.Format(),

View on GitHub (pinned to dbf9771522)

Solutions

  1. Configure the complex collection property to be mapped to JSON using .ToJson("ColumnName") so the index becomes a valid JSON-path index.
  2. Remove the index that traverses the complex collection — indexes over complex collections that aren't JSON-mapped are not supported.
  3. Denormalize the indexed scalar out of the complex collection into a top-level column on the entity and index that instead.

Example fix

// before: complex collection without JSON mapping, index traverses it
modelBuilder.Entity<Customer>()
    .ComplexProperty(c => c.Addresses, ab =>
    {
        ab.IsCollection();
    });
modelBuilder.Entity<Customer>().HasIndex("Addresses.ZipCode"); // throws

// after: map the complex collection to JSON
modelBuilder.Entity<Customer>()
    .ComplexProperty(c => c.Addresses, ab =>
    {
        ab.ToJson("addresses");
    });
modelBuilder.Entity<Customer>().HasIndex("Addresses.ZipCode");
Defensive patterns

Strategy: validation

Validate before calling

// Ensure complex collections used in indexes are mapped to JSON.
foreach (var index in modelBuilder.Model.GetEntityTypes().SelectMany(e => e.GetIndexes()))
{
    if (index.CollectionIndices is null) continue;
    for (var i = 0; i < index.Properties.Count; i++)
    {
        if (index.CollectionIndices[i] is null) continue;
        var prop = index.Properties[i];
        var container = prop.DeclaringType is IComplexType ct && ct.IsMappedToJson()
            ? ct.GetContainerColumnName()
            : (prop is IComplexProperty cp && cp.ComplexType.IsMappedToJson()
                ? cp.ComplexType.GetContainerColumnName() : null);
        if (container is null)
            Console.WriteLine($"Index property '{prop.Name}' traverses a complex collection but has no JSON column — add ToJson().");
    }
}

Prevention

When it happens

Trigger: Creating an index over a property inside a complex property that is a collection (HasIndex with a lambda traversing a collection) where the complex type is NOT configured with ToJson. The index builder records CollectionIndices, but GetContainerColumnName returns null because IsMappedToJson() is false.

Common situations: Indexing a nested property inside a complex collection (e.g., HasIndex(e => e.Items.First().Name)) without configuring the complex property with .ToJson("column_name"). Attempting to create database indexes across table-per-column complex type collections.

Related errors


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