dotnet/efcore · error · InvalidOperationException
Trying to evaluate a non-expression condition in expression
Error message
Trying to evaluate a non-expression condition in expression context
What it means
Thrown in TranslateConditional when ifTrue or ifFalse translate to something that is not an ExpressionSyntax (e.g. a statement). In pure expression context, both arms must be expressions; if an arm lifts to a statement and the context is not an expression lambda, there is no fallback path. InvalidOperationException. Part of EF Core's LINQ-to-C# syntax translation.
Source
Thrown at src/EFCore.Design/Query/Internal/LinqToCSharpSyntaxTranslator.cs:854
{
throw new NotSupportedException(
$"Missing {nameof(ConditionalExpression.IfFalse)} in "
+ "{nameof(System.Linq.Expressions.ConditionalExpression)} in expression context");
}
var parentLiftedState = _liftedState;
_liftedState = parentLiftedState.CreateChild();
// If we're in a lambda body, we try to translate as an expression if possible (i.e. no blocks in the true/false arms).
using (ChangeContext(ExpressionContext.Expression))
{
var ifTrue = Translate(conditional.IfTrue);
var ifFalse = Translate(conditional.IfFalse);
if (ifTrue is not ExpressionSyntax ifTrueExpression
|| ifFalse is not ExpressionSyntax ifFalseExpression)
{
throw new InvalidOperationException("Trying to evaluate a non-expression condition in expression context");
}
// There were no lifted expressions inside either arm - we can translate directly to a C# conditional expression
if (_liftedState.Statements.Count == 0)
{
_liftedState = parentLiftedState;
return ParenthesizedExpression(ConditionalExpression(test, ifTrueExpression, ifFalseExpression));
}
}
// If we're in a lambda body and couldn't translate as a conditional expression, translate as an if/else statement with
// return. Wrap the true/false sides in blocks to have "return" added.
if (_context == ExpressionContext.ExpressionLambda)
{
_liftedState = parentLiftedState;
return Block(
TranslateConditionalStatement(View on GitHub (pinned to dbf9771522)
Solutions
- Translate the enclosing expression in statement or expression-lambda context so arms can lift to if/else.
- Simplify the conditional arms to single expressions.
Defensive patterns
Strategy: validation
Validate before calling
// Avoid translating a conditional with non-expression arms in expression context
foreach (var cond in expr.DescendantsAndSelf().OfType<ConditionalExpression>())
{
if (cond.IfTrue is BlockExpression || cond.IfTrue is TryExpression
|| cond.IfFalse is BlockExpression || cond.IfFalse is TryExpression)
{
// These arms cannot be single expressions; require statement/lambda context
context = ExpressionContext.ExpressionLambda;
}
} Prevention
- Keep conditional arms as single expressions when translating in plain expression context.
- Switch to expression-lambda or statement context when arms contain blocks.
When it happens
Trigger: A conditional whose arm translates to a statement/block rather than an expression, encountered in plain expression (non-lambda) context where lifting to if/else is not available.
Common situations: Expression trees where a conditional arm contains a block or try/catch that cannot be a single expression, in a context that cannot lift to statements.
Related errors
- Lifted expressions remaining at top-level in expression cont
- Parameter clash during expression lifting for: {parameter.Na
- Label on last expression of an expression block
- Missing IfFalse in {nameof(System.Linq.Expressions.Condition
- Lambda with null expression body
AI-assisted analysis of dotnet/efcore@dbf9771522 (2026-08-06).
Data as JSON: /api/errors/271650d977830e8a.
Report an issue: GitHub.