dotnet/efcore · error · NotSupportedException

Lambda with null expression body

Error message

Lambda with null expression body

What it means

Thrown by CSharpToLinqTranslator.VisitLambdaExpression when a lambda's ExpressionBody is null. The translator only handles expression-bodied lambdas (x => x + 1) because it produces a single LINQ Expression, not a statement tree; statement lambdas with block bodies ((x) => { ... }) are rejected. This is part of EF Core's precompiled-query infrastructure that parses Roslyn C# syntax back into LINQ expression trees.

Source

Thrown at src/EFCore.Design/Query/Internal/CSharpToLinqTranslator.cs:1032

        var type = ResolveType(typeSymbol);
        return Constant(type, typeof(Type));
    }

    /// <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 override Expression DefaultVisit(SyntaxNode node)
        => throw new NotSupportedException($"Unsupported syntax node of type '{node.GetType()}': {node}");

    private Expression VisitLambdaExpression(AnonymousFunctionExpressionSyntax lambda, Type? expectedType = null)
    {
        if (lambda.ExpressionBody is null)
        {
            throw new NotSupportedException("Lambda with null expression body");
        }

        if (lambda.Modifiers.Any())
        {
            throw new NotSupportedException("Lambda with modifiers not supported: " + lambda.Modifiers);
        }

        if (!lambda.AsyncKeyword.IsKind(SyntaxKind.None))
        {
            throw new NotSupportedException("Async lambdas are not supported");
        }

        var lambdaParameters = lambda switch
        {
            SimpleLambdaExpressionSyntax simpleLambda => SyntaxFactory.SingletonSeparatedList(simpleLambda.Parameter),
            ParenthesizedLambdaExpressionSyntax parenthesizedLambda => parenthesizedLambda.ParameterList.Parameters,

            _ => throw new UnreachableException()

View on GitHub (pinned to dbf9771522)

Solutions

  1. Rewrite the lambda as an expression-bodied lambda (single expression, no braces).
  2. Extract multi-statement logic into a separate method and reference it as a single expression.
  3. Simplify the query predicate to a single boolean expression.

Example fix

// before
.Where(x => { if (x.Age < 18) return false; return x.Name.StartsWith("A"); })
// after
.Where(x => x.Age >= 18 && x.Name.StartsWith("A"))
Defensive patterns

Strategy: validation

Validate before calling

// Before translating user query source, scan lambdas for block bodies
foreach (var lambda in root.DescendantNodes().OfType<AnonymousFunctionExpressionSyntax>())
{
    if (lambda.ExpressionBody is null)
        throw new InvalidOperationException(
            $"Statement-bodied lambda at {lambda.GetLocation()} is not supported; use an expression-bodied lambda.");
}

Prevention

When it happens

Trigger: Translating C# source containing a statement-bodied lambda (braces) passed to a LINQ operator during precompiled query processing; any AnonymousFunctionExpressionSyntax where lambda.ExpressionBody is null.

Common situations: Writing a precompiled query predicate with multiple statements inside braces; using method-group or block lambdas in code that gets processed by the C#-to-LINQ translator; malformed syntax trees from a source generator.

Related errors


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