dotnet/efcore · error · InvalidOperationException

Unhandled expression

Error message

Unhandled expression '{expression}' of type '{expressionType}' encountered in '{visitor}'.

What it means

Thrown by CosmosQuerySqlGenerator in its Expression switch default arm: a SqlExpression subclass arrived that the generator has no Visit method for. The supported set is ScalarReferenceExpression, ScalarSubqueryExpression, SelectExpression, SourceExpression, SqlBinaryExpression, SqlConditionalExpression, SqlConstantExpression, SqlFunctionExpression, SqlParameterExpression, SqlUnaryExpression, StructuralTypeProjectionExpression. Anything else indicates either a new SqlExpression type the Cosmos generator does not yet handle, or a query that the translator built into an unsupported shape.

Solutions

  1. Rewrite the query to a simpler form the Cosmos SQL dialect supports (Cosmos SQL is a subset of T-SQL).
  2. Move the unsupported operation to the client via AsEnumerable/ToList before it reaches SQL generation.
  3. Confirm you are on the latest EF Core Cosmos patch; if the error persists on a standard query, file an issue with the full expression tree.

Example fix

// before - aggregate/construct Cosmos cannot generate SQL for
var r = ctx.Docs.GroupBy(d => d.Cat).Select(g => new { g.Key, Max = g.Max(d => d.Score) });

// after - aggregate client-side
var r = ctx.Docs.AsEnumerable()
    .GroupBy(d => d.Cat)
    .Select(g => new { g.Key, Max = g.Max(d => d.Score) });
Defensive patterns

Strategy: try-catch

Try / catch

try { var r = await ctx.Docs.GroupBy(d => d.Cat).Select(g => new { g.Key, Max = g.Max(d => d.Score) }).ToListAsync(); }
catch (InvalidOperationException ex) when (ex.Message.Contains("Unhandled expression") || ex.Message.Contains("could not be translated"))
{ var raw = await ctx.Docs.AsNoTracking().ToListAsync();
  var r = raw.GroupBy(d => d.Cat).Select(g => new { g.Key, Max = g.Max(d => d.Score) }); }

Prevention

When it happens

Trigger: Writing a LINQ query whose translation produces a SqlExpression not in the generator's dispatch table (e.g. a newly supported relational expression type, or a provider extension). Usually surfaces as an internal InvalidOperationException at SQL-generation time.

Common situations: Upgrading EF Core where the relational layer emits a new SqlExpression kind the Cosmos generator has not been updated for; using query features (e.g. complex aggregates, window-like constructs) only relational supports; provider plugins injecting SqlExpression subclasses.

Related errors


AI-assisted analysis of dotnet/efcore@3a2006ef56 (2026-08-11). Data as JSON: /api/errors/59441af89c3534a5. Report an issue: GitHub.

Appendix: source

Thrown at src/EFCore.Cosmos/Query/Internal/CosmosQuerySqlGenerator.cs:97

            ObjectFunctionExpression e => VisitObjectFunction(e),
            ObjectReferenceExpression e => VisitObjectReference(e),
            OrderingExpression e => VisitOrdering(e),
            ProjectionExpression e => VisitProjection(e),
            ScalarAccessExpression e => VisitScalarAccess(e),
            ScalarArrayExpression e => VisitScalarArray(e),
            ScalarReferenceExpression e => VisitValueReference(e),
            ScalarSubqueryExpression e => VisitScalarSubquery(e),
            SelectExpression e => VisitSelect(e),
            SourceExpression e => VisitSource(e),
            SqlBinaryExpression e => VisitSqlBinary(e),
            SqlConditionalExpression e => VisitSqlConditional(e),
            SqlConstantExpression e => VisitSqlConstant(e),
            SqlFunctionExpression e => VisitSqlFunction(e),
            SqlParameterExpression e => VisitSqlParameter(e),
            SqlUnaryExpression e => VisitSqlUnary(e),
            StructuralTypeProjectionExpression e => VisitStructuralTypeProjection(e),

            _ => throw new InvalidOperationException(
                CosmosStrings.UnhandledExpressionInVisitor(expression, expression.GetType(), nameof(CosmosQuerySqlGenerator))),
        };

    /// <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>
    protected virtual Expression VisitStructuralTypeProjection(StructuralTypeProjectionExpression structuralTypeProjectionExpression)
    {
        Visit(structuralTypeProjectionExpression.Object);

        return structuralTypeProjectionExpression;
    }

    /// <summary>
    ///     This is an internal API that supports the Entity Framework Core infrastructure and not subject to

View on GitHub (pinned to 3a2006ef56)