dotnet/efcore · error · NotSupportedException
Lifted expressions remaining at top-level in expression cont
Error message
Lifted expressions remaining at top-level in expression context
What it means
Thrown at the end of TranslateCore when translating in expression context but _liftedState.Statements.Count > 0. Some sub-expressions needed to be 'lifted' into separate statements (blocks, multi-arm conditionals), but at top-level expression context there is no enclosing statement scope to lift into. Part of EF Core's LINQ-to-C# syntax translation (compiled models / precompiled queries).
Source
Thrown at src/EFCore.Design/Query/Internal/LinqToCSharpSyntaxTranslator.cs:174
try
{
Visit(node);
}
finally
{
if (constantReplacements != null)
{
foreach (var name in constantReplacements.Values)
{
rootFrame.VariableNames.Remove(name);
}
}
}
if (_liftedState.Statements.Count > 0
&& _context == ExpressionContext.Expression)
{
throw new NotSupportedException("Lifted expressions remaining at top-level in expression context");
}
Check.DebugAssert(_stack.Count == 1, "_parameterStack.Count == 1");
Check.DebugAssert(_stack.Peek().Variables.Count == 0, "_stack.Peek().Parameters.Count == 0");
Check.DebugAssert(_stack.Peek().VariableNames.Count == 0, "_stack.Peek().ParameterNames.Count == 0");
Check.DebugAssert(_stack.Peek().Labels.Count == 0);
Check.DebugAssert(_stack.Peek().UniqueLabelNames.Count == 0);
foreach (var unsafeAccessor in _fieldUnsafeAccessors.Values.Concat(_methodUnsafeAccessors.Values))
{
unsafeAccessors.Add(unsafeAccessor);
}
return Result!;
}
/// <summary>
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject toView on GitHub (pinned to dbf9771522)
Solutions
- Use TranslateStatement instead of TranslateExpression if the expression contains blocks or other constructs requiring lifting.
- Simplify the expression to avoid constructs that require lifting.
Defensive patterns
Strategy: validation
Validate before calling
// Choose the right translation entry point based on whether lifting is needed
var needsStatements = ContainsBlockOrLiftableConstruct(node);
var result = needsStatements
? translator.TranslateStatement(node, replacements, namespaces, accessors)
: translator.TranslateExpression(node, replacements, namespaces, accessors); Prevention
- Use TranslateStatement for any expression containing blocks, try/catch, or multi-arm conditionals.
- Reserve TranslateExpression for pure single-expression trees.
When it happens
Trigger: Translating an expression that contains statement-like constructs (blocks, multi-arm conditionals) at the top level via TranslateExpression rather than TranslateStatement.
Common situations: Calling TranslateExpression on an expression tree that actually requires statement-form translation; expression tree shapes the translator did not expect at top level; internal API misuse.
Related errors
- Lambda with null expression body
- Lambda with modifiers not supported: {lambda.Modifiers}
- Async lambdas are not supported
- Got translated node of type '{Result?.GetType().Name ?? "<nu
- Parameter clash during expression lifting for: {parameter.Na
AI-assisted analysis of dotnet/efcore@dbf9771522 (2026-08-06).
Data as JSON: /api/errors/8872763c4f7b6327.
Report an issue: GitHub.