dotnet/efcore · error · NotSupportedException
Unsupported syntax node of type '{node.GetType()}': {node}
Error message
Unsupported syntax node of type '{node.GetType()}': {node} What it means
DefaultVisit is the catch-all that throws NotSupportedException for any C# syntax node type lacking a specific Visit* override. It is the generic 'this C# construct is not supported in precompiled queries' error; the node type in the message identifies the offending construct.
Source
Thrown at src/EFCore.Design/Query/Internal/CSharpToLinqTranslator.cs:1026
{
if (_semanticModel.GetSymbolInfo(typeOf.Type).Symbol is not ITypeSymbol typeSymbol)
{
throw new InvalidOperationException(
"Could not find symbol for typeof() expression: " + typeOf);
}
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");
}
View on GitHub (pinned to dbf9771522)
Solutions
- Identify the unsupported construct from the node type printed in the message
- Rewrite using simpler expression-based constructs that map to expression trees
- Hoist unsupported logic out of the query into a captured local computed beforehand
Example fix
// before (switch expression, unsupported)
var q = ctx.Items.Select(i => i.Kind switch { 1 => "a", _ => "b" });
// after (ternary, supported)
var q = ctx.Items.Select(i => i.Kind == 1 ? "a" : "b"); Defensive patterns
Strategy: validation
Validate before calling
// Scan precompiled query source for constructs the translator cannot visit.
// Flag: switch expressions, pattern matching 'is', null-conditional '?.', statement-bodied lambdas,
// lock/using/checked blocks, tuple expressions.
static bool UsesUnsupported(string src) =>
System.Text.RegularExpressions.Regex.IsMatch(src, @"switch\s*\{|\bis\s+\w+\s+\w+|\?\.|=>\s*\{");
if (UsesUnsupported(querySource)) { /* rewrite to expression-tree-friendly form */ } Prevention
- Keep precompiled query bodies as simple expression-tree-friendly expressions
- Rewrite switch expressions as nested ternaries
- Replace null-conditional access with explicit null checks
- Hoist complex logic out of the query into captured locals
When it happens
Trigger: Using a C# construct the translator has no visitor for: statement-bodied lambdas, lock/using/checked/unchecked blocks, switch expressions, pattern-matching 'is', tuple expressions, null-conditional ?., query continuations (into), etc.
Common situations: Writing modern/advanced C# (pattern matching, switch expressions, null-conditional operators) or statement-style code inside a query that gets precompiled.
Related errors
- ArrayCreation: non-array type symbol: {implicitArrayCreation
- ArrayCreation: multi-dimensional array: {implicitArrayCreati
- Could not find symbol for method invocation: {invocation}
- Invocation over non-member access: {invocation}
- Invocation: couldn't find method '{methodSymbol.Name}' on ty
AI-assisted analysis of dotnet/efcore@dbf9771522 (2026-08-06).
Data as JSON: /api/errors/f9d6b44ff5de897e.
Report an issue: GitHub.