dotnet/efcore · error · InvalidOperationException

The 'VectorDistance' function can only be used with a proper

Error message

The 'VectorDistance' function can only be used with a property mapped as a vector. Use 'IsVectorProperty()' in 'OnModelCreating' to configure the property as a vector.

What it means

EF.Functions.VectorDistance requires at least one of its two vector operands to be a property configured as a Cosmos vector (i.e., it carries a CosmosVectorTypeMapping). The translator at CosmosVectorSearchTranslator.cs:57-59 checks both operands' type mappings and throws if neither is a vector property. Without a vector mapping EF cannot determine the vector data type, dimensions, and distance function needed to generate valid SQL.

Source

Thrown at src/EFCore.Cosmos/Query/Internal/Translators/CosmosVectorSearchTranslator.cs:59

        }

        if (useBruteForceExpression is not SqlConstantExpression { Value: var useBruteForceValue })
        {
            throw new InvalidOperationException(
                CoreStrings.ArgumentNotConstant("useBruteForce", nameof(CosmosDbFunctionsExtensions.VectorDistance)));
        }

        if (optionsExpression is not SqlConstantExpression { Value: var optionsValue })
        {
            throw new InvalidOperationException(
                CoreStrings.ArgumentNotConstant("options", nameof(CosmosDbFunctionsExtensions.VectorDistance)));
        }

        var options = (VectorDistanceOptions?)optionsValue;

        var vectorMapping = vector1.TypeMapping as CosmosVectorTypeMapping
            ?? vector2.TypeMapping as CosmosVectorTypeMapping
            ?? throw new InvalidOperationException(CosmosStrings.VectorSearchRequiresVector);

        var vectorType = vectorMapping.VectorType;

        List<Expression> newArguments =
        [
            sqlExpressionFactory.ApplyTypeMapping(vector1, vectorMapping), sqlExpressionFactory.ApplyTypeMapping(vector2, vectorMapping)
        ];

        if (useBruteForceValue is not null)
        {
            newArguments.Add(useBruteForceExpression);
        }

        if (options is not null)
        {
            // If the options are provided but not useBruteForce, we need to explicitly specify the default for the
            // latter (false)
            if (useBruteForceValue is null)

View on GitHub (pinned to dbf9771522)

Solutions

  1. In OnModelCreating, configure the embedding property: modelBuilder.Entity<T>().Property(x => x.Embedding).IsVectorProperty(DistanceFunction.Cosine, /*dimensions*/ 1536, VectorDataType.Float32).
  2. Ensure the property type is ReadOnlyMemory<float>, ReadOnlyMemory<byte>, or ReadOnlyMemory<sbyte> so EF can assign the CosmosVectorTypeMapping.
  3. Verify the VectorDistance call references the mapped property (e.g., e.Embedding) on at least one side.

Example fix

// before
modelBuilder.Entity<Document>().Property(d => d.Embedding); // not configured as vector

// after
modelBuilder.Entity<Document>()
    .Property(d => d.Embedding)
    .IsVectorProperty(DistanceFunction.Cosine, dimensions: 1536, VectorDataType.Float32);
Defensive patterns

Strategy: validation

Validate before calling

// After building the model, verify the embedding property has a vector type mapping.
var model = context.Model.FindEntityType(typeof(Document))!;
var embedding = model.GetProperties().First(p => p.Name == nameof(Document.Embedding));
var mapping = embedding.FindTypeMapping();
if (mapping is not CosmosVectorTypeMapping)
    throw new InvalidOperationException("Embedding property is not configured as a vector.");

Type guard

// Type guard to confirm a property is vector-mapped before querying
static bool IsVectorProperty(IProperty property)
    => property.FindTypeMapping() is CosmosVectorTypeMapping;

Prevention

When it happens

Trigger: Calling EF.Functions.VectorDistance(e.SomeProperty, queryVector, null, null) where 'SomeProperty' is not configured with IsVectorProperty() in OnModelCreating, or calling it with two runtime-supplied ReadOnlyMemory values and no mapped property on either side.

Common situations: Forgetting to call IsVectorProperty() on the embedding property in the model. Applying vector search on a property that has a value converter masking its type. Renaming the property but not updating the vector configuration.

Related errors


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