litedb-org/LiteDB · error · NotSupportedException
Invalid BsonExpression when converted from Linq expression:
Error message
Invalid BsonExpression when converted from Linq expression: {_expr.ToString()} - `{expression}` What it means
A catch-all thrown by LinqExpressionVisitor.Resolve when BsonExpression.Create fails to parse the string that the visitor built from the LINQ expression. The visitor translated the expression tree into a BsonExpression string, but that string is syntactically or semantically invalid. The original LINQ expression and the generated string are both included to aid debugging, and the original parse exception is passed as the inner exception.
Source
Thrown at LiteDB/Client/Mapper/Linq/LinqExpressionVisitor.cs:88
var expression = _builder.ToString();
try
{
var e = BsonExpression.Create(expression, _parameters);
// if expression must return an predicate but expression result is Path/Parameter/Call add `= true`
if (predicate && (e.Type == BsonExpressionType.Path || e.Type == BsonExpressionType.Call || e.Type == BsonExpressionType.Parameter))
{
expression = "(" + expression + " = true)";
e = BsonExpression.Create(expression, _parameters);
}
return e;
}
catch (Exception ex)
{
throw new NotSupportedException($"Invalid BsonExpression when converted from Linq expression: {_expr.ToString()} - `{expression}`", ex);
}
}
/// <summary>
/// Visit :: `x => x.Customer.Name`
/// </summary>
protected override Expression VisitLambda<T>(Expression<T> node)
{
var l = base.VisitLambda(node);
// remove last parameter $ (or @)
_builder.Length--;
return l;
}
/// <summary>
/// Visit lambda invocationView on GitHub (pinned to f906a5f850)
Solutions
- Read the inner exception (ex.InnerException) for the exact token/parse error and the generated BsonExpression string to pinpoint the bad fragment.
- Simplify the LINQ expression incrementally to isolate which sub-expression produces the invalid output.
- Replace the failing LINQ predicate with a raw BsonExpression string via Query.Where() or the string-based Find overload.
- Check LiteDB release notes for known translation gaps and supported LINQ surface.
Example fix
// before -- complex LINQ that fails translation
var results = col.Find(x => x.Items.Select(i => i.Price * i.Qty).Sum() > 100);
// after -- use a raw BsonExpression string
var results = col.Find("MAP($.Items[*], @0 => @0.Price * @0.Qty) SUM > 100"); Defensive patterns
Strategy: try-catch
Validate before calling
// Validate the expression by attempting a dry-run translation at test time
try
{
var test = mapper.GetExpression<MyEntity, bool>(x => x.ComplexPredicate);
}
catch (NotSupportedException)
{
// This LINQ construct cannot be translated -- plan to use BsonExpression instead
} Try / catch
try
{
var results = col.Find(predicate);
}
catch (NotSupportedException ex) when (ex.Message.Contains("Invalid BsonExpression when converted"))
{
logger.LogWarning("LINQ translation failed: {Expr}", ex.Message);
results = col.Find(rawBsonExpression);
} Prevention
- Keep LINQ query expressions simple and within the known-supported surface.
- Write integration tests that exercise each query predicate to catch translation failures early.
- Have a raw BsonExpression fallback ready for complex predicates.
- Check the inner exception for the exact BsonExpression parse error to pinpoint the fragment.
When it happens
Trigger: Any LINQ expression whose translation produces a BsonExpression string that BsonExpression.Create cannot parse. This is the fallback for constructs that pass individual Visit stages but combine into an invalid final expression. The inner exception holds the precise tokenizer/parse error.
Common situations: Complex nested expressions (e.g., combining unsupported method chains with binary operators) that partially translate but produce malformed output. Using LINQ constructs at the edge of the translator's supported surface that yield a near-valid but ultimately unparseable BsonExpression string. Version differences where a construct worked before but the translation changed.
Related errors
- 0
- Extend expression must return an anonymous class to be merge
- Multiple OrderBy calls are not supported. Use ThenBy for add
- GROUP BY already defined in this query
- field
AI-assisted analysis of litedb-org/LiteDB@f906a5f850 (2026-08-13).
Data as JSON: /api/errors/4c20e8cb8e2e777f.
Report an issue: GitHub.