{"record":{"id":"f9d6b44ff5de897e","repo":"dotnet/efcore","slug":"unsupported-syntax-node-of-type-node-gettype","errorCode":null,"errorMessage":"Unsupported syntax node of type '{node.GetType()}': {node}","messagePattern":"Unsupported syntax node of type '(.+?)': (.+?)","errorType":"exception","errorClass":"NotSupportedException","httpStatus":null,"severity":"error","filePath":"src/EFCore.Design/Query/Internal/CSharpToLinqTranslator.cs","lineNumber":1026,"sourceCode":"    {\n        if (_semanticModel.GetSymbolInfo(typeOf.Type).Symbol is not ITypeSymbol typeSymbol)\n        {\n            throw new InvalidOperationException(\n                \"Could not find symbol for typeof() expression: \" + typeOf);\n        }\n\n        var type = ResolveType(typeSymbol);\n        return Constant(type, typeof(Type));\n    }\n\n    /// <summary>\n    ///     This is an internal API that supports the Entity Framework Core infrastructure and not subject to\n    ///     the same compatibility standards as public APIs. It may be changed or removed without notice in\n    ///     any release. You should only use it directly in your code with extreme caution and knowing that\n    ///     doing so can result in application failures when updating to a new Entity Framework Core release.\n    /// </summary>\n    public override Expression DefaultVisit(SyntaxNode node)\n        => throw new NotSupportedException($\"Unsupported syntax node of type '{node.GetType()}': {node}\");\n\n    private Expression VisitLambdaExpression(AnonymousFunctionExpressionSyntax lambda, Type? expectedType = null)\n    {\n        if (lambda.ExpressionBody is null)\n        {\n            throw new NotSupportedException(\"Lambda with null expression body\");\n        }\n\n        if (lambda.Modifiers.Any())\n        {\n            throw new NotSupportedException(\"Lambda with modifiers not supported: \" + lambda.Modifiers);\n        }\n\n        if (!lambda.AsyncKeyword.IsKind(SyntaxKind.None))\n        {\n            throw new NotSupportedException(\"Async lambdas are not supported\");\n        }\n","sourceCodeStart":1008,"sourceCodeEnd":1044,"githubUrl":"https://github.com/dotnet/efcore/blob/3a2006ef569de08368d59db5e1468aa8f407e4f8/src/EFCore.Design/Query/Internal/CSharpToLinqTranslator.cs#L1008-L1044","documentation":"Thrown by DefaultVisit — the catch-all override that fires for ANY C# syntax node type that does not have a specific Visit override in the translator. This is the ultimate fallback: if the translator encounters a syntax construct it has no handler for (no VisitXxx override matched), DefaultVisit throws NotSupportedException. The message includes the node's runtime type and its full text for diagnosis.","triggerScenarios":"Any C# expression construct not explicitly handled by a Visit override triggers this. Examples include: checked/unchecked expressions, sizeof expressions, stackalloc expressions, default value expressions in some forms, tuple expressions, switch expressions, switch statements, pattern matching (is-pattern), conditional access (?.) in certain positions, range expressions, interpolated string handlers in complex forms, ref expressions, yield expressions, local function declarations, lock/fixed/using statements, and any new C# language feature not yet supported by the translator.","commonSituations":"Using newer C# language features (C# 10-13+) inside precompiled queries before the translator is updated to support them; using pattern matching (switch expressions, `is` patterns) in query predicates; using tuple deconstruction in projections; using checked arithmetic; using conditional access expressions (`entity?.Property`); using interpolation with complex format providers. The most common trigger is simply writing modern idiomatic C# in a query that gets precompiled.","solutions":["Identify the unsupported construct from the error message (it includes the node type name) and rewrite it using a more basic form the translator handles.","Replace switch expressions/patterns with if-else chains or ternary operators.","Replace conditional access (x?.Y) with explicit null checks (x != null ? x.Y : null).","Replace tuple syntax with anonymous objects or separate variable bindings.","Replace checked/unchecked with unchecked method calls or remove the checked context.","If the construct is essential, exclude the query from precompilation or file an EF Core issue for support.","Check the EF Core release notes — newer versions may have added support for the construct you're using."],"exampleFix":"// before — switch expression (DefaultVisit catch-all)\nvar query = ctx.Orders.Select(o => o.Status switch {\n    Status.Pending => 0,\n    Status.Shipped => 1,\n    _ => 2\n});\n\n// after — conditional expression\nvar query = ctx.Orders.Select(o =>\n    o.Status == Status.Pending ? 0 :\n    o.Status == Status.Shipped ? 1 : 2);","handlingStrategy":"validation","validationCode":"// Before precompiling, identify syntax node types that will hit DefaultVisit\nvar knownOverrides = new HashSet<string> {\n    nameof(CSharpSyntaxVisitor<Expression>.VisitBinaryExpression),\n    nameof(CSharpSyntaxVisitor<Expression>.VisitInvocationExpression),\n    nameof(CSharpSyntaxVisitor<Expression>.VisitMemberAccessExpression),\n    nameof(CSharpSyntaxVisitor<Expression>.VisitObjectCreationExpression),\n    nameof(CSharpSyntaxVisitor<Expression>.VisitSimpleLambdaExpression),\n    nameof(CSharpSyntaxVisitor<Expression>.VisitParenthesizedLambdaExpression),\n    nameof(CSharpSyntaxVisitor<Expression>.VisitLiteralExpression),\n    // ... (all overridden Visit methods in CSharpToLinqTranslator)\n};\n// Any node whose CSharpSyntaxVisitor dispatches to DefaultVisit will trigger the error\nvar unhandledNodes = querySyntaxTree.DescendantNodes()\n    .Where(n => IsDispatchedToDefaultVisit(n)); // requires knowing the visitor's override set\nif (unhandledNodes.Any())\n    ReportError($\"Unsupported syntax node(s): {string.Join(\", \", unhandledNodes.Select(n => n.GetType().Name))}\");","typeGuard":null,"tryCatchPattern":"// If invoking the translator programmatically:\ntry { var expr = translator.Translate(node, semanticModel); }\ncatch (NotSupportedException ex) when (ex.Message.Contains(\"Unsupported syntax node\"))\n{\n    // Log the unsupported construct and fall back to runtime compilation\n    LogPrecompileSkipped(node, ex.Message);\n    // The query will compile normally at runtime without precompilation\n}","preventionTips":["Write precompiled queries using only basic C# constructs: property access, arithmetic, ternary operators, and standard method calls.","Avoid modern C# features (switch expressions, patterns, tuples, ranges) inside precompiled query lambdas until confirmed supported.","Replace conditional access (x?.Y) with explicit null checks (x != null ? x.Y : null).","Replace pattern matching with if-else or ternary chains.","Check EF Core release notes for newly supported syntax constructs with each version.","Run precompilation in CI to catch unsupported constructs early.","Keep precompiled query code deliberately simple and separate complex logic into translatable helper methods."],"tags":["precompiled-queries","roslyn","default-visit","unsupported-syntax","catch-all","csharp-syntax","expression-tree"],"backgroundTag":null,"analyzedSha":"3a2006ef569de08368d59db5e1468aa8f407e4f8","analyzedAt":"2026-08-11T23:42:04.146Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}