dotnet/efcore · error · InvalidOperationException
Ordering based on scoring function is not supported inside
Error message
Ordering based on scoring function is not supported inside '{orderByDescending}'. Use '{orderBy}' instead. What it means
ApplyOrdering in Cosmos SelectExpression throws when an ordering expression is a scoring function (IsScoringFunction, e.g. VectorDistance or FullTextScore) and IsAscending is false. Cosmos DB scoring orderings must be ascending; descending a score reverses its semantic and is rejected. The user must call OrderBy, not OrderByDescending, for scoring functions.
Solutions
- Use OrderBy instead of OrderByDescending for the scoring function.
- If you genuinely need inverse-ranked results, redesign the query or apply client-side reversal after materialization (without Skip/Take).
Example fix
// before
var q = db.Items
.OrderByDescending(i => EF.Functions.VectorDistance(i.Embedding, query));
// after
var q = db.Items
.OrderBy(i => EF.Functions.VectorDistance(i.Embedding, query)); Defensive patterns
Strategy: validation
Validate before calling
// Reject OrderByDescending over scoring functions at the query builder boundary.
static bool IsScoringExpression(Expression e) =>
e is MethodCallExpression m && m.Method.Name is "VectorDistance" or "FullTextScore";
static bool IsValidOrdering(MethodCallExpression call) =>
!(call.Method.Name == nameof(Queryable.OrderByDescending) && IsScoringExpression(((UnaryExpression)call.Arguments[1]).Operand)); Prevention
- Use OrderBy for all scoring-function orderings in Cosmos queries.
- Add a code-review/lint check that flags OrderByDescending(EF.Functions.VectorDistance|FullTextScore).
- Document in your data-access layer that scoring orderings are ascending-only.
When it happens
Trigger: Queryable.OrderByDescending(EF.Functions.VectorDistance(...)) or OrderByDescending(EF.Functions.FullTextScore(...)).
Common situations: Attempting to retrieve least-relevant results by descending the score; copy-pasting an OrderByDescending pattern that worked for a property onto a vector/full-text score.
Related errors
- Only one ordering using scoring function is allowed. Use…
- Ordering using a scoring function is mutually exclusive…
- A vector index is defined for
- A vector index on ' ' is defined over properties ` `. A…
- Creating a container with full-text search or vector…
AI-assisted analysis of dotnet/efcore@3a2006ef56 (2026-08-11).
Data as JSON: /api/errors/06ea8fcc7ab421b8.
Report an issue: GitHub.
Appendix: source
Thrown at src/EFCore.Cosmos/Query/Internal/Expressions/SelectExpression.cs:462
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
/// the same compatibility standards as public APIs. It may be changed or removed without notice in
/// any release. You should only use it directly in your code with extreme caution and knowing that
/// doing so can result in application failures when updating to a new Entity Framework Core release.
/// </summary>
public void ApplyOffset(SqlExpression sqlExpression)
=> Offset = sqlExpression;
/// <summary>
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
/// the same compatibility standards as public APIs. It may be changed or removed without notice in
/// any release. You should only use it directly in your code with extreme caution and knowing that
/// doing so can result in application failures when updating to a new Entity Framework Core release.
/// </summary>
public void ApplyOrdering(OrderingExpression orderingExpression)
{
if (orderingExpression is { Expression: SqlFunctionExpression { IsScoringFunction: true }, IsAscending: false })
{
throw new InvalidOperationException(
CosmosStrings.OrderByDescendingScoringFunction(nameof(Queryable.OrderByDescending), nameof(Queryable.OrderBy)));
}
_orderings.Clear();
_orderings.Add(orderingExpression);
}
/// <summary>
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
/// the same compatibility standards as public APIs. It may be changed or removed without notice in
/// any release. You should only use it directly in your code with extreme caution and knowing that
/// doing so can result in application failures when updating to a new Entity Framework Core release.
/// </summary>
public void AppendOrdering(OrderingExpression orderingExpression)
{
if (_orderings.Count > 0)
{
var existingScoringFunctionOrdering = _orderings is [{ Expression: SqlFunctionExpression { IsScoringFunction: true } }];View on GitHub (pinned to 3a2006ef56)