litedb-org/LiteDB · error · ArgumentException
HAVING already defined in this query
Error message
HAVING already defined in this query
What it means
Thrown by LiteQueryable.Having(BsonExpression) when _query.Having is already non-null. Like GroupBy, Having is stored as a single optional expression, so only one HAVING clause per query is supported. Having is intended to filter aggregated groups and must follow a GroupBy.
Source
Thrown at LiteDB/Client/Database/LiteQueryable.cs:210
/// </summary>
public ILiteQueryable<T> GroupBy(BsonExpression keySelector)
{
if (_query.GroupBy != null) throw new ArgumentException("GROUP BY already defined in this query");
_query.GroupBy = keySelector;
return this;
}
#endregion
#region Having
/// <summary>
/// Filter documents after group by pipe according to predicate expression (requires GroupBy and support only one Having)
/// </summary>
public ILiteQueryable<T> Having(BsonExpression predicate)
{
if (_query.Having != null) throw new ArgumentException("HAVING already defined in this query");
_query.Having = predicate;
return this;
}
#endregion
#region Select
/// <summary>
/// Transform input document into a new output document. Can be used with each document, group by or all source
/// </summary>
public ILiteQueryable<BsonDocument> Select(BsonExpression selector)
{
_query.Select = selector;
return new LiteQueryable<BsonDocument>(_engine, _mapper, _collection, _query);
}View on GitHub (pinned to f906a5f850)
Solutions
- Merge multiple predicates into one Having expression joined with AND, e.g. Having("$.sum > 10 AND $.count < 5").
- Build the combined predicate string once before calling Having.
- If predicate parts come from optional inputs, concatenate only the non-null fragments.
Example fix
// before
var q = col.Query()
.GroupBy("$.Category")
.Having("$.sum > 10")
.Having("$.count < 5");
// after
var q = col.Query()
.GroupBy("$.Category")
.Having("$.sum > 10 AND $.count < 5"); Defensive patterns
Strategy: validation
Validate before calling
// Accumulate Having fragments and join with AND once.
var predicates = new List<string>();
if (minSum.HasValue) predicates.Add($"$.sum > {minSum}");
if (maxCount.HasValue) predicates.Add($"$.count < {maxCount}");
if (predicates.Count > 0) q.Having(string.Join(" AND ", predicates)); Prevention
- Collect optional Having fragments in a list and join once.
- Reserve Having for post-aggregation filters only.
When it happens
Trigger: Chaining two Having calls on the same query: col.Query().GroupBy("$.Category").Having("$.sum > 10").Having("$.count < 5").
Common situations: Adding multiple post-aggregation filters by chaining (mimicking SQL AND semantics), or appending a Having from a filter-composition helper that runs more than once.
Related errors
- GROUP BY already defined in this query
- Multiple OrderBy calls are not supported. Use ThenBy for add
- At least two Query should be passed
- 0
- GROUP BY expression do not support INCLUDE
AI-assisted analysis of litedb-org/LiteDB@f906a5f850 (2026-08-13).
Data as JSON: /api/errors/5708b04994da3ec9.
Report an issue: GitHub.