litedb-org/LiteDB · error · ArgumentException

GROUP BY already defined in this query

Error message

GROUP BY already defined in this query

What it means

Thrown by LiteQueryable.GroupBy(BsonExpression) when _query.GroupBy is already non-null. A query may have exactly one GROUP BY clause; the method stores the expression in a single field rather than a list, so a second assignment is rejected. The strongly-typed GroupBy<K> overload delegates here after registering the grouping type.

Source

Thrown at LiteDB/Client/Database/LiteQueryable.cs:195

        /// Groups the documents of resultset according to a specified key selector expression (support only one GroupBy)
        /// </summary>
        public ILiteQueryable<IGrouping<K, T>> GroupBy<K>(Expression<Func<T, K>> keySelector)
        {
            var expression = _mapper.GetExpression(keySelector);

            this.GroupBy(expression);

            _mapper.RegisterGroupingType<K, T>();

            return new LiteQueryable<IGrouping<K, T>>(_engine, _mapper, _collection, _query);
        }

        /// <summary>
        /// Groups the documents of resultset according to a specified key selector expression (support only one GroupBy)
        /// </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;

View on GitHub (pinned to f906a5f850)

Solutions

  1. Combine multiple grouping fields into a single BsonExpression, e.g. GroupBy("$.Category + '|' + $.Region").
  2. If you need hierarchical grouping, perform a second grouping step on the materialized results client-side.
  3. Build the full group key expression once and pass it to a single GroupBy call.

Example fix

// before
var q = col.Query().GroupBy("$.Category").GroupBy("$.Region");

// after
var q = col.Query().GroupBy("$.Category + '|' + $.Region");
Defensive patterns

Strategy: validation

Validate before calling

// Compose a single composite group key before calling GroupBy.
var groupExpr = string.Join(" + '|' + ", keys.Select(k => $"$.{k}"));
q.GroupBy(groupExpr);

Prevention

When it happens

Trigger: Calling the BsonExpression overload twice: col.Query().GroupBy("$.Category").GroupBy("$.Region"), or chaining after the strongly-typed overload returns an ILiteQueryable<T> that still exposes GroupBy(BsonExpression).

Common situations: Trying to group by a composite key by chaining two GroupBy calls (as in some SQL dialects), or refactoring a query builder that appends grouping clauses.

Related errors


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