{"record":{"id":"61187ff70779a3b6","repo":"dotnet/efcore","slug":"encountered-non-quotable-expression-of-type-node","errorCode":null,"errorMessage":"Encountered non-quotable expression of type {node.GetType()} when translating expression tree to C#","messagePattern":"Encountered non-quotable expression of type (.+?) when translating expression tree to C#","errorType":"exception","errorClass":"NotSupportedException","httpStatus":null,"severity":"error","filePath":"src/EFCore.Design/Query/Internal/LinqToCSharpSyntaxTranslator.cs","lineNumber":2691,"sourceCode":"\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    protected override Expression VisitExtension(Expression node)\n    {\n        // TODO: Remove any EF-specific code from this visitor (extend if needed)\n        // TODO: Hack mode. Visit the expression beforehand to replace EntityQueryRootExpression with context.Set<>(), or receive it in this visitor as a replacement or something.\n        if (node is EntityQueryRootExpression entityQueryRoot)\n        {\n            // TODO: STET\n            Result = ParseExpression($\"context.Set<{entityQueryRoot.EntityType.ClrType.Name}>()\");\n            return node;\n        }\n\n        throw new NotSupportedException(\n            $\"Encountered non-quotable expression of type {node.GetType()} when translating expression tree to C#\");\n    }\n\n    private ArgumentSyntax[] TranslateMethodArguments(ParameterInfo[] parameters, IReadOnlyList<Expression> arguments)\n    {\n        var translatedExpressions = TranslateList(arguments);\n        var translatedArguments = new ArgumentSyntax[arguments.Count];\n\n        for (var i = 0; i < translatedExpressions.Length; i++)\n        {\n            var parameter = parameters[i];\n            var argument = Argument(translatedExpressions[i]);\n\n            if (parameter.IsOut)\n            {\n                argument = argument.WithRefKindKeyword(Token(SyntaxKind.OutKeyword));\n            }\n            else if (parameter.IsIn)","sourceCodeStart":2673,"sourceCodeEnd":2709,"githubUrl":"https://github.com/dotnet/efcore/blob/dbf9771522148d61a2467854921bd5dc6f6e6916/src/EFCore.Design/Query/Internal/LinqToCSharpSyntaxTranslator.cs#L2673-L2709","documentation":"Thrown by the expression-tree-to-C# translator (LinqToCSharpSyntaxTranslator.VisitExtension, line 2691) that backs EF Core's precompiled-query feature. It only knows how to render EntityQueryRootExpression nodes back into C#; any other extension Expression node type it cannot quote into source code causes this NotSupportedException. It surfaces as a query precompilation failure when generating the C# interceptor source for a query whose tree contains a node the translator was never taught to handle.","triggerScenarios":"Running precompiled query generation ('dotnet ef dbcontext optimize' with precompiled queries, or the PrecompiledQueryCodeGenerator pipeline) over a LINQ query whose parsed expression tree contains a non-EF extension Expression node that is not an EntityQueryRootExpression. VisitExtension's single handled case is EntityQueryRootExpression; everything else hits the throw.","commonSituations":"Using a third-party or custom Expression-derived node in a query (e.g. a provider-specific query root, a custom SQL/FromSql expression node, or an extension injected by another EF extension library). Hitting an EF Core version where a newly added query-root type is not yet recognised by the translator. Mixing EF extensions that emit proprietary expression nodes into a query targeted for precompilation.","solutions":["Remove or simplify the part of the LINQ query that introduces the unsupported expression node (e.g. drop the custom extension/operator causing the non-EF node) so the tree only contains standard EF nodes.","Exclude the offending query from precompiled-query generation and let it run through the normal EF query pipeline instead.","Upgrade EF Core to a version that recognises the expression node type shown in the message (the type name is printed via node.GetType()).","If you control the expression, avoid injecting custom extension nodes into queries you intend to precompile; keep those queries to standard LINQ/EF operators."],"exampleFix":"// before: a query using a custom extension that injects a non-EF expression node\nvar q = db.Blogs.Where(b => b.Id > 0).UseMyCustomOperator();\n\n// after: drop the unsupported operator for the query being precompiled\nvar q = db.Blogs.Where(b => b.Id > 0);","handlingStrategy":"try-catch","validationCode":"// Before precompiling, sanity-check the query tree for non-EF extension nodes\nstatic bool HasOnlyKnownRoots(Expression e) => e is not Expression\n    || e is EntityQueryRootExpression\n    || e.NodeType != ExpressionType.Extension;\n\n// (Best validated by precompiling a query in isolation first; if it fails, simplify it.)","typeGuard":"static bool IsSupportedQueryRoot(Expression e)\n    => e is EntityQueryRootExpression || e.NodeType != ExpressionType.Extension;","tryCatchPattern":"// Precompiled-query pipelines collect failures; if invoking directly, catch NotSupportedException\ntry\n{\n    // run precompiled-query generation for the query\n}\ncatch (NotSupportedException ex) when (ex.Message.Contains(\"non-quotable expression\"))\n{\n    // log the query, exclude it from precompilation, fall back to normal execution\n}","preventionTips":["Keep precompiled queries limited to standard LINQ + EF operators; avoid injecting custom extension expression nodes.","Precompile queries incrementally to catch unsupported nodes early.","Track the set of EF expression types your queries depend on."],"tags":["ef-core","precompiled-query","expression-tree","design-time"],"analyzedSha":"dbf9771522148d61a2467854921bd5dc6f6e6916","analyzedAt":"2026-08-06T20:46:03.226Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}