{"record":{"id":"cb9996b3cabaa7d7","repo":"dotnet/efcore","slug":"a-full-text-index-on-entitytype-is-defined-ove-cb9996","errorCode":null,"errorMessage":"A full-text index on '{entityType}' is defined over multiple properties (`{properties}`). A full-text index can only target a single property.","messagePattern":"A full-text index on '(.+?)' is defined over multiple properties \\(`(.+?)`\\)\\. A full-text index can only target a single property\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/EFCore.Cosmos/Storage/Internal/CosmosClientWrapper.cs","lineNumber":200,"sourceCode":"            {\n                if (index.Properties.Count > 1)\n                {\n                    throw new InvalidOperationException(\n                        CosmosStrings.CompositeVectorIndex(\n                            index.DeclaringEntityType.DisplayName(),\n                            string.Join(\",\", index.Properties.Select(e => e.Name))));\n                }\n\n                vectorIndexes.Add(\n                    new VectorIndexPath { Path = GetJsonPropertyPathFromRoot(index.Properties[0]), Type = vectorIndexType.Value });\n                continue;\n            }\n\n            if (index.IsFullTextIndex() == true)\n            {\n                if (index.Properties.Count > 1)\n                {\n                    throw new InvalidOperationException(\n                        CosmosStrings.CompositeFullTextIndex(\n                            index.DeclaringEntityType.DisplayName(),\n                            string.Join(\",\", index.Properties.Select(e => e.Name))));\n                }\n\n                fullTextIndexPaths.Add(\n                    new FullTextIndexPath { Path = GetJsonPropertyPathFromRoot(index.Properties[0]) });\n                continue;\n            }\n\n            var isConvention = index is IConventionIndex convIndex\n                && convIndex.GetConfigurationSource() == ConfigurationSource.Convention;\n\n            if (index.Properties.Count == 1)\n            {\n                var path = GetJsonPropertyPathFromRoot(index.Properties[0]) + \"/?\";\n                if (seenIncludedPaths.Add(path))\n                {","sourceCodeStart":182,"sourceCodeEnd":218,"githubUrl":"https://github.com/dotnet/efcore/blob/dbf9771522148d61a2467854921bd5dc6f6e6916/src/EFCore.Cosmos/Storage/Internal/CosmosClientWrapper.cs#L182-L218","documentation":"Azure Cosmos DB full-text indexes can only target a single property path. During container creation (CosmosClientWrapper.cs:198-204), EF Core rejects any index where IsFullTextIndex() is true and Properties.Count exceeds 1. A composite full-text index is not supported by the Cosmos full-text policy schema.","triggerScenarios":"Configuring an index over multiple properties and enabling full-text search on it, e.g. modelBuilder.Entity<T>().HasIndex([x => x.Title, x => x.Body]).ForCosmos().IsFullTextIndex(). This fires at container-creation time.","commonSituations":"Wanting to full-text search across multiple text columns and assuming a composite index covers them. Copying a relational composite index and adding IsFullTextIndex(). Confusing full-text index (single property) with composite indexes (general purpose).","solutions":["Create a separate single-property full-text index for each property you want searchable: modelBuilder.Entity<T>().HasIndex(x => x.Title).ForCosmos().IsFullTextIndex(); and modelBuilder.Entity<T>().HasIndex(x => x.Body).ForCosmos().IsFullTextIndex().","Ensure each full-text index targets exactly one property.","Recreate the container after fixing the model."],"exampleFix":"// before\nmodelBuilder.Entity<Article>()\n    .HasIndex(a => new { a.Title, a.Body })\n    .ForCosmos()\n    .IsFullTextIndex();\n\n// after\nmodelBuilder.Entity<Article>().HasIndex(a => a.Title).ForCosmos().IsFullTextIndex();\nmodelBuilder.Entity<Article>().HasIndex(a => a.Body).ForCosmos().IsFullTextIndex();","handlingStrategy":"validation","validationCode":"// Validate that no full-text index spans multiple properties.\nforeach (var entityType in model.GetEntityTypes())\n{\n    foreach (var index in entityType.GetIndexes())\n    {\n        if (index.IsFullTextIndex() == true && index.Properties.Count > 1)\n            throw new InvalidOperationException($\"Full-text index on {entityType.DisplayName()} has multiple properties.\");\n    }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Create one single-property full-text index per searchable column.","Never combine multiple properties in a HasIndex() when calling IsFullTextIndex().","Add a model-validation test asserting full-text indexes target exactly one property."],"tags":["cosmos","full-text-search","index-configuration","container-creation"],"analyzedSha":"dbf9771522148d61a2467854921bd5dc6f6e6916","analyzedAt":"2026-08-06T20:46:03.226Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}