litedb-org/LiteDB · error · LiteException

0

0

Error message

WHERE filter can not use `*` expression in `{predicate.Source}`

What it means

Thrown by QueryOptimization.SplitWherePredicateInTerms when a WHERE predicate expression has UseSource == true, meaning it references the root document source token ('*'). LiteDB's WHERE clause filters individual documents field-by-field; a '*' source has no meaningful filter semantics and cannot be indexed. The optimizer rejects it during query planning.

Source

Thrown at LiteDB/Engine/Query/QueryOptimization.cs:85

            // define IncludeBefore + IncludeAfter
            this.DefineIncludes();

            return _queryPlan;
        }

        #region Split Where

        /// <summary>
        /// Fill terms from where predicate list
        /// </summary>
        private void SplitWherePredicateInTerms()
        {
            void add(BsonExpression predicate)
            {
                // do not accept source * in WHERE
                if (predicate.UseSource)
                {
                    throw new LiteException(0, $"WHERE filter can not use `*` expression in `{predicate.Source}");
                }

                // add expression in where list breaking AND statments
                if (predicate.IsPredicate || predicate.Type == BsonExpressionType.Or)
                {
                    _terms.Add(predicate);
                }
                else if (predicate.Type == BsonExpressionType.And)
                {
                    var left = predicate.Left;
                    var right = predicate.Right;

                    add(left);
                    add(right);
                }
                else
                {
                    throw LiteException.InvalidExpressionTypePredicate(predicate);

View on GitHub (pinned to f906a5f850)

Solutions

  1. Rewrite the WHERE predicate to reference a concrete field path (e.g. '$.field > 0') instead of '*'.
  2. If you need to test the whole document, target a specific field or use a function-based expression on a named path.
  3. Validate BsonExpression.UseSource is false before adding it to a Where list.
  4. Keep '*' usage limited to the SELECT clause where it is supported.

Example fix

// before — '*' in WHERE
db.Execute("SELECT $ FROM items WHERE * > 0"); // throws
// or in code:
var expr = BsonExpression.Create("* > 0");
query.Where.Add(expr); // throws at optimization

// after — reference a concrete field
db.Execute("SELECT $ FROM items WHERE $.value > 0");
Defensive patterns

Strategy: validation

Validate before calling

public void AddWhereClause(Query query, BsonExpression predicate)
{
    if (predicate.UseSource)
        throw new ArgumentException($"WHERE predicate '{predicate.Source}' uses the root source '*'. Rewrite it to reference a concrete field.");
    query.Where.Add(predicate);
}

Type guard

static bool IsSafeWherePredicate(BsonExpression predicate) =>
    predicate != null && !predicate.UseSource;

Try / catch

try
{
    db.Execute(sql);
}
catch (LiteException ex) when (ex.Message.Contains("WHERE filter can not use `*`"))
{
    throw new ArgumentException("The WHERE clause must reference concrete fields, not the root '*' source.", ex);
}

Prevention

When it happens

Trigger: Constructing a query whose WHERE expression uses the '*' / source wildcard, e.g. via BsonExpression.Create("* > 0") used as a Where clause, or SQL like 'SELECT $ FROM col WHERE * = ...'. Any predicate where predicate.UseSource is true in the Where list triggers the throw.

Common situations: Dynamically building BsonExpression filters and accidentally passing a root-source expression; misusing the '*' syntax (which is valid in SELECT but not WHERE); copy-paste from a SELECT template into a WHERE context.

Related errors


AI-assisted analysis of litedb-org/LiteDB@f906a5f850 (2026-08-13). Data as JSON: /api/errors/5b6002c2c83136c7. Report an issue: GitHub.