redis/redis-py · error · DataError
GROUPBY is not allowed when multiple aggregators are specifi
Error message
GROUPBY is not allowed when multiple aggregators are specified
What it means
Raised by the TS.MRANGE/TS.MREVRANGE parameter builder when groupby is set AND aggregation_type is a list with more than one aggregator. The server cannot apply GROUPBY REDUCE across multiple aggregators, so the combination is invalid. Use a single aggregator with GROUPBY, or drop GROUPBY when you need multiple aggregators.
Source
Thrown at redis/commands/timeseries/commands.py:1420
filter_by_ts: List[int] | None,
filter_by_min_value: int | None,
filter_by_max_value: int | None,
groupby: str | None,
reduce: str | None,
select_labels: List[str] | None,
align: int | str | None,
latest: bool | None,
bucket_timestamp: str | None,
empty: bool | None,
exclude_empty: bool | None,
):
"""Create TS.MRANGE and TS.MREVRANGE arguments."""
if (
groupby is not None
and isinstance(aggregation_type, list)
and len(aggregation_type) > 1
):
raise DataError(
"GROUPBY is not allowed when multiple aggregators are specified"
)
if exclude_empty and groupby is not None:
raise DataError("EXCLUDEEMPTY is not allowed with GROUPBY")
params: list[EncodableT] = [from_time, to_time]
self._append_latest(params, latest)
self._append_filer_by_ts(params, filter_by_ts)
self._append_filer_by_value(params, filter_by_min_value, filter_by_max_value)
self._append_with_labels(params, with_labels, select_labels)
self._append_count(params, count)
self._append_align(params, align)
self._append_aggregation(params, aggregation_type, bucket_size_msec)
self._append_bucket_timestamp(params, bucket_timestamp)
self._append_empty(params, empty)
self._append_exclude_empty(params, exclude_empty)
params.extend(["FILTER"])
params += filters
self._append_groupby_reduce(params, groupby, reduce)View on GitHub (pinned to da03cdc7e8)
Solutions
- Use a single aggregator when you need GROUPBY: aggregation_type='avg', groupby='region', reduce='sum'.
- Drop groupby/reduce to use multiple aggregators: aggregation_type=['avg','sum'] with groupby=None.
- Run two separate mrange calls if you need both grouping and multiple aggregations.
Example fix
// before
client.ts().mrange('-', '+', filters=f, aggregation_type=['avg','sum'], groupby='region', reduce='sum')
// after
client.ts().mrange('-', '+', filters=f, aggregation_type='avg', groupby='region', reduce='sum') Defensive patterns
Strategy: validation
Validate before calling
def validate_mrange_agg(agg_type, groupby):
if groupby is not None and isinstance(agg_type, list) and len(agg_type) > 1:
raise ValueError("Use a single aggregator with GROUPBY, or drop GROUPBY for multi-agg.")
return agg_type Type guard
def is_groupby_compatible(agg_type, groupby) -> bool:
if groupby is None:
return True
if isinstance(agg_type, list) and len(agg_type) > 1:
return False
return True Try / catch
try:
client.ts().mrange('-', '+', filters=f, aggregation_type=agg, groupby=g, reduce=r)
except Exception as e:
if 'GROUPBY' in str(e):
agg = agg[0] if isinstance(agg, list) else agg
client.ts().mrange('-', '+', filters=f, aggregation_type=agg, groupby=g, reduce=r)
else:
raise Prevention
- Keep GROUPBY paired with a single (string) aggregator.
- Only use aggregator lists when groupby is None.
- Document the mutual exclusion in your query helpers.
When it happens
Trigger: client.ts().mrange('-', '+', filters=['region=us'], aggregation_type=['avg','sum'], groupby='region', reduce='sum'). The check fires before the command is sent.
Common situations: Enabling multi-aggregator support (Redis 8.8+) while keeping an existing GROUPBY/REDUCE pipeline; copy-pasting a config that combined both; treating aggregation_type as always-list.
Related errors
- EXCLUDEEMPTY is not allowed with GROUPBY
- with_labels and select_labels cannot be provided together.
- AGGREGATION requires exactly one aggregation spec per key (e
- At least one key must be provided.
- filters cannot be an empty collection; pass None to query al
AI-assisted analysis of redis/redis-py@da03cdc7e8 (2026-08-04).
Data as JSON: /data/errors/09808a3faa3d1ef6.json.
Report an issue: GitHub.