dotnet/efcore · error · InvalidOperationException

The '{parameter}' value passed to '{methodName}' must be a c

Error message

The '{parameter}' value passed to '{methodName}' must be a constant.

What it means

The Cosmos DB VectorDistance SQL function requires the 'useBruteForce' argument to be a compile-time constant because EF Core must inline the literal value into the generated SQL at translation time. A non-constant expression (variable, column reference, or computed value) cannot be embedded into the query text. The translator at CosmosVectorSearchTranslator.cs:43-47 checks that the argument is a SqlConstantExpression and throws if it is not.

Source

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

        SqlExpression? instance,
        MethodInfo method,
        IReadOnlyList<SqlExpression> arguments,
        IDiagnosticsLogger<DbLoggerCategory.Query> logger)
    {
        if (method.DeclaringType != typeof(CosmosDbFunctionsExtensions)
            || method.Name != nameof(CosmosDbFunctionsExtensions.VectorDistance))
        {
            return null;
        }

        if (arguments is not [_, var vector1, var vector2, var useBruteForceExpression, var optionsExpression])
        {
            throw new UnreachableException();
        }

        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 =

View on GitHub (pinned to dbf9771522)

Solutions

  1. Pass a literal true, false, or null for the useBruteForce argument instead of a variable.
  2. If the value must vary at runtime, branch into two separate LINQ queries (one with brute-force true, one with false/null) and select between them in C# before executing.
  3. Omit the useBruteForce argument entirely (pass null) to use the default index-based behavior.

Example fix

// before
var bruteForce = config.GetValue<bool>("Vector:BruteForce");
var result = await db.Items
    .OrderBy(e => EF.Functions.VectorDistance(e.Embedding, q, bruteForce, null))
    .FirstAsync();

// after
var result = bruteForce
    ? await db.Items.OrderBy(e => EF.Functions.VectorDistance(e.Embedding, q, true, null)).FirstAsync()
    : await db.Items.OrderBy(e => EF.Functions.VectorDistance(e.Embedding, q, null, null)).FirstAsync();
Defensive patterns

Strategy: validation

Validate before calling

// Before building the query, ensure the useBruteForce value is a literal or null.
// There is no runtime type guard; the constraint is enforced at LINQ translation.
// Validate at the call site by only passing constants:
static IQueryable<Item> VectorSearch(AppDbContext db, ReadOnlyMemory<float> q, bool? bruteForce)
    => bruteForce switch
    {
        true => db.Items.OrderBy(e => EF.Functions.VectorDistance(e.Embedding, q, true, null)),
        false => db.Items.OrderBy(e => EF.Functions.VectorDistance(e.Embedding, q, false, null)),
        null => db.Items.OrderBy(e => EF.Functions.VectorDistance(e.Embedding, q, null, null)),
    };

Prevention

When it happens

Trigger: Calling EF.Functions.VectorDistance(e.Vector, queryVector, bruteForceVar, null) in a LINQ query where bruteForceVar is a runtime variable, method parameter, or any expression EF Core cannot fold to a constant. The 'useBruteForce' parameter is marked [NotParameterized] so it must resolve to a literal.

Common situations: Passing a configuration flag read from IConfiguration or appsettings at runtime as the brute-force argument. Using a method-level bool parameter to toggle brute-force mode. Conditionally building the argument with a ternary that EF cannot constant-fold.

Related errors


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