{"record":{"id":"5ec1c6005a197581","repo":"dotnet/efcore","slug":"a-full-text-index-on-entitytype-is-defined-ove","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/Infrastructure/Internal/CosmosModelValidator.cs","lineNumber":643,"sourceCode":"                CosmosStrings.VectorIndexOnNonVector(\n                    entityType.DisplayName(),\n                    index.Properties[0].Name));\n        }\n    }\n\n    /// <summary>\n    ///     This is an internal API that supports the Entity Framework Core infrastructure and not subject to\n    ///     the same compatibility standards as public APIs. It may be changed or removed without notice in\n    ///     any release. You should only use it directly in your code with extreme caution and knowing that\n    ///     doing so can result in application failures when updating to a new Entity Framework Core release.\n    /// </summary>\n    protected virtual void ValidateFullTextIndex(\n        IIndex index,\n        IDiagnosticsLogger<DbLoggerCategory.Model.Validation> logger)\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        if (index.Properties[0] is not IProperty firstFullTextProperty\n            || firstFullTextProperty.GetIsFullTextSearchEnabled() != true)\n        {\n            throw new InvalidOperationException(\n                CosmosStrings.FullTextIndexOnNonFullTextProperty(\n                    index.DeclaringEntityType.DisplayName(),\n                    index.Properties[0].Name,\n                    nameof(CosmosPropertyBuilderExtensions.EnableFullTextSearch)));\n        }\n    }\n\n    /// <summary>\n    ///     This is an internal API that supports the Entity Framework Core infrastructure and not subject to","sourceCodeStart":625,"sourceCodeEnd":661,"githubUrl":"https://github.com/dotnet/efcore/blob/dbf9771522148d61a2467854921bd5dc6f6e6916/src/EFCore.Cosmos/Infrastructure/Internal/CosmosModelValidator.cs#L625-L661","documentation":"Thrown by CosmosModelValidator.ValidateFullTextIndex when an index flagged as a Cosmos full-text index spans more than one property (index.Properties.Count > 1). Azure Cosmos DB full-text indexes are single-property by design, so EF Core rejects the composite configuration at model validation time rather than sending an invalid container policy. The thrown message interpolates the entity display name and the comma-joined property names.","triggerScenarios":"Calling HasFullTextIndex on an EntityTypeBuilder with more than one property argument, e.g. builder.HasIndex(x => new { x.Title, x.Body }).HasFullTextIndex(). The validator runs during model finalization when ValidateFullTextIndex inspects index.Properties.Count.","commonSituations":"Developers used to relational composite indexes assume Cosmos full-text search supports multi-column indexes. Migrating from SQL Server full-text (which allows multiple columns) to Cosmos without restructuring the index definitions.","solutions":["Split the single HasFullTextIndex call into one HasFullTextIndex per property, each on its own HasIndex builder for that one property.","Re-examine the model: if you truly need cross-property full-text search, combine the values into a single denormalized string property and full-text-index that property instead."],"exampleFix":"// before\nmodelBuilder.Entity<Article>()\n    .HasIndex(a => new { a.Title, a.Body })\n    .HasFullTextIndex();\n\n// after\nmodelBuilder.Entity<Article>().HasIndex(a => a.Title).HasFullTextIndex();\nmodelBuilder.Entity<Article>().HasIndex(a => a.Body).HasFullTextIndex();","handlingStrategy":"validation","validationCode":"// In OnModelCreating, before HasFullTextIndex, assert single property\nforeach (var index in modelBuilder.Model.GetEntityTypes().SelectMany(e => e.GetIndexes()))\n{\n    var props = index.Properties;\n    if (props.Count > 1 && /* is full-text: you track via a side map or metadata */) continue;\n    if (props.Count > 1) throw new InvalidOperationException($\"Full-text index on {index.DeclaringEntityType.DisplayName()} is composite.\");\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Centralize all HasFullTextIndex calls in one OnModelCreating region and visually verify each uses exactly one property.","Add a model-validation unit test that enumerates indexes and fails if any full-text index has >1 property."],"tags":["cosmos","ef-core","model-validation","full-text-index"],"analyzedSha":"dbf9771522148d61a2467854921bd5dc6f6e6916","analyzedAt":"2026-08-06T20:46:03.226Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}