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
- Rewrite the lambda as an expression-bodied lambda (single expression, no braces).
- Extract multi-statement logic into a separate method and reference it as a single expression.
- 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
- Use expression-bodied lambdas (no braces) in all query code intended for precompilation.
- Add a source-analyzer/roslyn analyzer rule that flags statement lambdas inside query operator calls.
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
- Lambda with modifiers not supported: {lambda.Modifiers}
- Async lambdas are not supported
- Lifted expressions remaining at top-level in expression cont
- Argument with ref/out: {argument}
- ArrayCreation: multi-dimensional array: {arrayCreation}
AI-assisted analysis of dotnet/efcore@dbf9771522 (2026-08-06).
Data as JSON: /api/errors/50e7f181d3b07b3c.
Report an issue: GitHub.