litedb-org/LiteDB · error · LiteException
0
0
Error message
Expression `{this.Source}` is not a scalar expression and can return more than one result What it means
Thrown by BsonExpression.ExecuteScalar when the expression's IsScalar flag is false, meaning the expression can yield zero or more values per document (an enumerable/path expression). ExecuteScalar demands a single-value (scalar) expression. This is a LiteException with code 0.
Source
Thrown at LiteDB/Document/Expression/BsonExpression.cs:274
public BsonValue ExecuteScalar(IEnumerable<BsonDocument> source, Collation collation = null)
{
if (source == null) throw new ArgumentNullException(nameof(source));
return this.ExecuteScalar(source, null, null, collation);
}
/// <summary>
/// Execute expression and returns IEnumerable values - returns NULL if no elements
/// </summary>
internal BsonValue ExecuteScalar(IEnumerable<BsonDocument> source, BsonDocument root, BsonValue current, Collation collation)
{
if (this.IsScalar)
{
return _funcScalar(source, root, current, collation ?? Collation.Binary, this.Parameters);
}
else
{
throw new LiteException(0, $"Expression `{this.Source}` is not a scalar expression and can return more than one result");
}
}
#endregion
#region Static method
private static readonly ConcurrentDictionary<string, BsonExpressionEnumerableDelegate> _cacheEnumerable = new ConcurrentDictionary<string, BsonExpressionEnumerableDelegate>();
private static readonly ConcurrentDictionary<string, BsonExpressionScalarDelegate> _cacheScalar = new ConcurrentDictionary<string, BsonExpressionScalarDelegate>();
/// <summary>
/// Parse string and create new instance of BsonExpression - can be cached
/// </summary>
public static BsonExpression Create(string expression)
{
return Create(expression, new BsonDocument());
}
View on GitHub (pinned to f906a5f850)
Solutions
- Check `expr.IsScalar` before calling ExecuteScalar; if false, use the enumerable execution path (Execute) instead.
- Rewrite the expression to produce a single value, e.g., wrap with an aggregate (MIN, MAX, COUNT) or select a specific index `$.items[0]`.
- Validate user-supplied expression strings at parse time using BsonExpression.Create and inspect IsScalar.
Example fix
// before
var result = expr.ExecuteScalar(docs);
// after
var result = expr.IsScalar
? expr.ExecuteScalar(docs)
: expr.Execute(docs).FirstOrDefault() ?? BsonValue.Null; Defensive patterns
Strategy: validation
Validate before calling
if (!expr.IsScalar) throw new InvalidOperationException($"Expression '{expr.Source}' is not scalar; use Execute() instead.");
var result = expr.ExecuteScalar(source); Type guard
static bool IsScalarExpression(BsonExpression expr) => expr != null && expr.IsScalar;
Try / catch
try { return expr.ExecuteScalar(source); }
catch (LiteException ex) when (ex.Message.Contains("not a scalar expression"))
{ /* fall back to enumerable execution or report to caller */ } Prevention
- Inspect expr.IsScalar immediately after BsonExpression.Create.
- Prefer Execute().FirstOrDefault() for expressions of unknown cardinality.
- Document which expressions are scalar vs enumerable in your query builder.
When it happens
Trigger: Calling ExecuteScalar on an expression containing array paths (e.g., `$.items[*]`), MAP, FILTER, or any operator that produces multiple results. Using a multi-result expression where a single value is required (e.g., in a BETWEEN bound, an index key, or a scalar aggregation slot).
Common situations: Building dynamic expressions where the user-supplied query contains a wildcard or multi-value path, then calling ExecuteScalar. Using an aggregate-style expression in a scalar context. Expression caching where a previously enumerable expression is reused in a scalar call site.
Related errors
AI-assisted analysis of litedb-org/LiteDB@f906a5f850 (2026-08-13).
Data as JSON: /api/errors/5e4687fe7fb926e6.
Report an issue: GitHub.