redis/redis-py · error · DataError
filters cannot be an empty collection; pass None to query…
Error message
filters cannot be an empty collection; pass None to query all indexed series.
What it means
Raised by _append_filter_expressions (used by TS.QUERYLABELS) when filters is an explicitly empty collection. None means 'query all indexed series' (FILTER omitted); an empty list is treated as a likely caller bug because silently widening to all series would be surprising.
Solutions
- Pass None (or omit filters) to query all indexed series.
- Pass a non-empty list of filter expressions.
- Guard dynamic filters: filters = filter_list or None.
Example fix
// before client.ts().querylabels(filters=[]) // after client.ts().querylabels(filters=None) # or client.ts().querylabels(filters=filter_list or None)
Defensive patterns
Strategy: validation
Validate before calling
filters = filters if filters else None client.ts().querylabels(filters=filters)
Try / catch
from redis.exceptions import DataError
try:
client.ts().querylabels(filters=filters)
except DataError:
client.ts().querylabels(filters=None) Prevention
- Use None (not []) to mean 'no filter'.
- Normalize empty iterables to None at call boundaries.
When it happens
Trigger: Calling client.ts().querylabels(filters=[]) or querylabels(filters=iter([])). Passing a list that resolved to empty.
Common situations: Building filters from user input that produced no expressions. Mistakenly passing an empty list to mean 'no filter'.
Related errors
- 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…
- Both ignore_max_time_diff and ignore_max_val_diff must be…
- EXCLUDEEMPTY is not allowed with GROUPBY
AI-assisted analysis of redis/redis-py@6a6b581b48 (2026-08-10).
Data as JSON: /api/errors/791f15a0030738fc.
Report an issue: GitHub.
Appendix: source
Thrown at redis/commands/timeseries/commands.py:1926
@staticmethod
def _append_filter_expressions(
params: list[EncodableT], filters: Iterable[str] | None
):
"""Append the optional FILTER clause for TS.QUERYLABELS.
``None`` omits ``FILTER`` entirely (the documented all-series query);
an explicitly empty collection is a local usage error, since silently
widening to all series would be surprising. Any iterable is accepted and
materialized once so single-pass iterators are handled correctly.
Expressions are passed through verbatim, without parsing, reordering, or
normalizing.
"""
if filters is None:
return
filters = list(filters)
if not filters:
raise DataError(
"filters cannot be an empty collection; pass None to query "
"all indexed series."
)
params.append("FILTER")
params.extend(filters)
@staticmethod
def _append_uncompressed(params: list[EncodableT], uncompressed: bool | None):
"""Append UNCOMPRESSED tag to params."""
if uncompressed:
params.extend(["ENCODING", "UNCOMPRESSED"])
@staticmethod
def _append_with_labels(
params: list[EncodableT],
with_labels: bool | None,
select_labels: list[str] | None,
):View on GitHub (pinned to 6a6b581b48)