redis/redis-py · error · DataError
EXCLUDEEMPTY is not allowed with GROUPBY
Error message
EXCLUDEEMPTY is not allowed with GROUPBY
What it means
Raised by the TS.MRANGE / TS.MREVRANGE parameter builder when both exclude_empty=True and a groupby value are supplied. EXCLUDEEMPTY filters out empty buckets, but GROUPBY collapses series into groups whose emptiness semantics conflict with that filter, so the combination is rejected client-side.
Solutions
- Set exclude_empty=False (or omit it) when using groupby.
- Drop groupby if you need EXCLUDEEMPTY behavior.
- Centralize option validation in your wrapper so the two are never combined.
Example fix
// before
client.ts().mrange(f, t, filters,
groupby='region', reduce='avg', exclude_empty=True)
// after
client.ts().mrange(f, t, filters,
groupby='region', reduce='avg') # exclude_empty omitted Defensive patterns
Strategy: validation
Validate before calling
if groupby:
exclude_empty = False
client.ts().mrange(..., groupby=groupby, reduce=reduce, exclude_empty=exclude_empty) Try / catch
from redis.exceptions import DataError
try:
client.ts().mrange(..., groupby=groupby, reduce=reduce, exclude_empty=exclude_empty)
except DataError:
client.ts().mrange(..., groupby=groupby, reduce=reduce) Prevention
- Treat exclude_empty and groupby as mutually exclusive in option builders.
- Centralize mrange option assembly to enforce invariants.
When it happens
Trigger: Calling mrange(..., groupby='region', reduce='avg', exclude_empty=True).
Common situations: Enabling exclude_empty globally in a helper that also sets groupby for some queries. Copying options between calls without checking mutual exclusivity.
Related errors
- GROUPBY is not allowed when multiple aggregators are…
- with_labels and select_labels cannot be provided together.
- AGGREGATION requires exactly one aggregation spec per key
- At least one key must be provided.
- block_min_count requires block_milliseconds to be set; the…
AI-assisted analysis of redis/redis-py@6a6b581b48 (2026-08-10).
Data as JSON: /api/errors/fc7f318345da2fed.
Report an issue: GitHub.
Appendix: source
Thrown at redis/commands/timeseries/commands.py:1424
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)
return params
@overload
def mrange(View on GitHub (pinned to 6a6b581b48)