{"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/3a2006ef569de08368d59db5e1468aa8f407e4f8/src/EFCore.Cosmos/Storage/Internal/CosmosClientWrapper.cs#L182-L218","documentation":"CosmosClientWrapper throws CompositeFullTextIndex when building container indexing policy and encounters a full-text index whose index.Properties contains more than one property. Cosmos DB full-text indexes must target exactly one property; composite full-text indexes are not supported.","triggerScenarios":"Defining an index over multiple properties and marking it as a full-text index, e.g. modelBuilder.Entity<T>().HasIndex(x => new { x.A, x.B }).IsFullTextIndex().","commonSituations":"Reusing a composite index definition and applying full-text configuration to all its paths; bulk index configuration.","solutions":["Define the full-text index over exactly one (string) property.","Define a separate single-property full-text index for each searchable string property."],"exampleFix":"// before\nmodelBuilder.Entity<Doc>()\n    .HasIndex(x => new { x.Title, x.Body })\n    .IsFullTextIndex();\n\n// after - one full-text index per property\nmodelBuilder.Entity<Doc>().HasIndex(x => x.Title).IsFullTextIndex();\nmodelBuilder.Entity<Doc>().HasIndex(x => x.Body).IsFullTextIndex();","handlingStrategy":"validation","validationCode":"// At model build, assert full-text indexes target exactly one property.\nforeach (var idx in entityType.GetIndexes())\n{\n    if (idx.IsFullTextIndex() == true && idx.Properties.Count > 1)\n        throw new InvalidOperationException($\"Full-text index on {entityType.DisplayName()} targets multiple properties.\");\n}","typeGuard":"static bool IsSinglePropertyFullTextIndex(IIndex idx) => idx.IsFullTextIndex() == true && idx.Properties.Count == 1;","tryCatchPattern":null,"preventionTips":["Define full-text indexes over a single string property only.","Add a model-build validator that rejects multi-property full-text indexes.","Review all HasIndex(...).IsFullTextIndex() calls during code review."],"tags":["cosmos","indexing","full-text-search","model"],"backgroundTag":null,"analyzedSha":"3a2006ef569de08368d59db5e1468aa8f407e4f8","analyzedAt":"2026-08-11T23:42:04.146Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}