{"record":{"id":"3528b7b620d21214","repo":"dotnet/efcore","slug":"a-vector-index-on-entitytype-is-defined-over-p","errorCode":null,"errorMessage":"A vector index on '{entityType}' is defined over properties `{properties}`. A vector index can only target a single property.","messagePattern":"A vector index on '(.+?)' is defined over properties `(.+?)`\\. A vector index can only target a single property\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/EFCore.Cosmos/Infrastructure/Internal/CosmosModelValidator.cs","lineNumber":614,"sourceCode":"    {\n        // Cosmos maps every property to JSON; no additional validation is needed here.\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 ValidateVectorIndex(\n        IIndex index,\n        IDiagnosticsLogger<DbLoggerCategory.Model.Validation> logger)\n    {\n        var entityType = index.DeclaringEntityType;\n\n        if (index.Properties.Count > 1)\n        {\n            throw new InvalidOperationException(\n                CosmosStrings.CompositeVectorIndex(\n                    entityType.DisplayName(),\n                    string.Join(\",\", index.Properties.Select(e => e.Name))));\n        }\n\n        if (index.Properties[0] is not IProperty firstVectorIndexProperty\n            || firstVectorIndexProperty.GetVectorDistanceFunction() == null\n            || firstVectorIndexProperty.GetVectorDimensions() == null)\n        {\n            throw new InvalidOperationException(\n                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","sourceCodeStart":596,"sourceCodeEnd":632,"githubUrl":"https://github.com/dotnet/efcore/blob/3a2006ef569de08368d59db5e1468aa8f407e4f8/src/EFCore.Cosmos/Infrastructure/Internal/CosmosModelValidator.cs#L596-L632","documentation":"Thrown when a vector index is defined over more than one property. Cosmos vector indexes target a single vector field, so EF Core rejects composite vector indexes. The validator checks index.Properties.Count and throws CompositeVectorIndex if it exceeds 1.","triggerScenarios":"Calling HasIndex(x => new { x.VecA, x.VecB }).HasVectorIndex(...) (a composite vector index) where two or more properties are included. Fires during ValidateVectorIndex for any index whose GetVectorIndexType() is non-null.","commonSituations":"Copy-pasting a composite relational index pattern and adding a vector-index call to it; building multi-vector search before realizing Cosmos supports only one vector per index; refactoring an index that grew to include a second vector property.","solutions":["Split the composite into separate single-property vector indexes, one per vector field.","If you intended a hybrid (vector + filter) index, drop the non-vector properties from the index definition - filter on them via the query instead.","Keep regular indexes and vector indexes as separate HasIndex calls."],"exampleFix":"// before\nmodelBuilder.Entity<Document>()\n    .HasIndex(d => new { d.TitleVector, d.BodyVector })\n    .HasVectorIndex(DistanceFunction.Cosine, 1536);\n\n// after\nmodelBuilder.Entity<Document>().HasIndex(d => d.TitleVector).HasVectorIndex(DistanceFunction.Cosine, 1536);\nmodelBuilder.Entity<Document>().HasIndex(d => d.BodyVector).HasVectorIndex(DistanceFunction.Cosine, 1536);","handlingStrategy":"validation","validationCode":"foreach (var et in dbContext.Model.GetEntityTypes())\n{\n    foreach (var idx in et.GetIndexes())\n    {\n        if (idx.GetVectorIndexType() is not null && idx.Properties.Count > 1)\n            throw new InvalidOperationException($\"{et.DisplayName()} has a composite vector index\");\n    }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Define vector indexes over a single property each.","Keep relational-style composite HasIndex expressions separate from vector indexes.","Add a CI test asserting every vector index targets exactly one property."],"tags":["cosmos","model-validation","vector-index","configuration"],"backgroundTag":null,"analyzedSha":"3a2006ef569de08368d59db5e1468aa8f407e4f8","analyzedAt":"2026-08-11T23:42:04.146Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}