{"record":{"id":"d0c114be380f4935","repo":"litedb-org/LiteDB","slug":"expression-expr-tostring-must-be-a-lambda-expr","errorCode":null,"errorMessage":"Expression {expr.ToString()} must be a lambda expression","messagePattern":"Expression (.+?) must be a lambda expression","errorType":"exception","errorClass":"NotSupportedException","httpStatus":null,"severity":"error","filePath":"LiteDB/Client/Mapper/Linq/LinqExpressionVisitor.cs","lineNumber":60,"sourceCode":"        private readonly BsonDocument _parameters = new BsonDocument();\n        private int _paramIndex = 0;\n        private Type _dbRefType = null;\n\n        private readonly StringBuilder _builder = new StringBuilder();\n        private readonly Stack<MemberExpression> _memberAccessNodes = new();\n\n        public LinqExpressionVisitor(BsonMapper mapper, Expression expr)\n        {\n            _mapper = mapper;\n            _expr = expr;\n\n            if (expr is LambdaExpression lambda)\n            {\n                _rootParameter = lambda.Parameters.First();\n            }\n            else\n            {\n                throw new NotSupportedException($\"Expression {expr.ToString()} must be a lambda expression\");\n            }\n        }\n\n        public BsonExpression Resolve(bool predicate)\n        {\n            this.Visit(_expr);\n\n            ENSURE(_memberAccessNodes.Count == 0, \"Member access node stack must be empty when finish expression resolve\");\n\n            var expression = _builder.ToString();\n\n            try\n            {\n                var e = BsonExpression.Create(expression, _parameters);\n\n                // if expression must return an predicate but expression result is Path/Parameter/Call add `= true`\n                if (predicate && (e.Type == BsonExpressionType.Path || e.Type == BsonExpressionType.Call || e.Type == BsonExpressionType.Parameter))\n                {","sourceCodeStart":42,"sourceCodeEnd":78,"githubUrl":"https://github.com/litedb-org/LiteDB/blob/f906a5f850678719e39a39a006cb66dcae563cfa/LiteDB/Client/Mapper/Linq/LinqExpressionVisitor.cs#L42-L78","documentation":"Thrown by the LinqExpressionVisitor constructor when the expression passed is not a LambdaExpression. The visitor needs a lambda to extract its root parameter, which drives all downstream member-access resolution. Without a lambda there is no parameter context to translate against.","triggerScenarios":"Constructing a LinqExpressionVisitor with an Expression that is not a LambdaExpression (e.g., a bare MemberExpression, ConstantExpression, or MethodCallExpression).","commonSituations":"Effectively unreachable from the public API surface: GetExpression<T,K> and GetIndexExpression<T,K> both accept Expression<Func<T,K>> which is always a lambda. Could surface if the visitor is instantiated via reflection or in a custom BsonMapper subclass that passes a raw non-lambda Expression.","solutions":["Always pass a lambda expression (x => x.Something) to the LINQ query APIs (Find, Query.Where, etc.).","Do not construct LinqExpressionVisitor directly; use BsonMapper.GetExpression or GetIndexExpression.","If subclassing BsonMapper, ensure any override that builds a LinqExpressionVisitor passes a lambda expression."],"exampleFix":null,"handlingStrategy":"type-guard","validationCode":"// Ensure the expression is a lambda before passing to query APIs\nstatic void EnsureLambda<T>(Expression<T> expr)\n{\n    if (expr is not LambdaExpression)\n        throw new ArgumentException(\"Expression must be a lambda.\", nameof(expr));\n}","typeGuard":"// Type guard: Expression<Func<T,K>> is always a lambda at the type level.\n// If building expressions dynamically:\nstatic bool IsLambdaExpression(Expression expr) => expr is LambdaExpression;","tryCatchPattern":"try\n{\n    var bsonExpr = mapper.GetExpression<MyEntity, bool>(predicate);\n}\ncatch (NotSupportedException ex) when (ex.Message.Contains(\"must be a lambda expression\"))\n{\n    throw new InvalidOperationException(\"Query predicate must be a lambda expression.\", ex);\n}","preventionTips":["Always use typed lambdas (Expression<Func<T,K>>) with GetExpression/GetIndexExpression.","Never construct LinqExpressionVisitor directly with a raw Expression.","If dynamically building expressions, wrap them in Expression.Lambda before use."],"tags":["linq","lambda","expression"],"backgroundTag":null,"analyzedSha":"f906a5f850678719e39a39a006cb66dcae563cfa","analyzedAt":"2026-08-13T21:56:30.148Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}