redis/redis-py · error · DataError
At least one key must be provided.
Error message
At least one key must be provided.
What it means
Raised by the TS.NRANGE/TS.NREVRANGE parameter builder (__n_range_params) when the keys list is empty. These multi-key commands require at least one time-series key; an empty list would send numkeys=0, which the server rejects. The library validates client-side for a clearer error.
Source
Thrown at redis/commands/timeseries/commands.py:1106
def __n_range_params(
self,
keys: List[KeyT],
from_time: int | str,
to_time: int | str,
count: int | None,
aggregators: str | list[str] | None,
bucket_size_msec: int | None,
filter_by_ts: List[int] | None,
filter_by_min_value: int | None,
filter_by_max_value: int | None,
align: int | str | None,
latest: bool | None,
bucket_timestamp: str | None,
empty: bool | None,
):
"""Create TS.NRANGE and TS.NREVRANGE arguments."""
if not keys:
raise DataError("At least one key must be provided.")
# numkeys is always derived from the key list and precedes the keys;
# key order and duplicates are preserved and map to output columns.
params: list[EncodableT] = [len(keys), *keys, 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_count(params, count)
self._append_align(params, align)
self._append_n_aggregation(params, aggregators, bucket_size_msec, len(keys))
self._append_bucket_timestamp(params, bucket_timestamp)
self._append_empty(params, empty)
return params
@overload
def nrange(
self: SyncClientProtocol,
keys: List[KeyT],View on GitHub (pinned to da03cdc7e8)
Solutions
- Ensure the keys list is non-empty before calling: if keys: client.ts().nrange(keys, '-', '+').
- Fix the upstream lookup so it returns the intended keys.
- If you genuinely have no keys, skip the query and return an empty result.
Example fix
// before
client.ts().nrange(keys, '-', '+') # keys == []
// after
if keys:
client.ts().nrange(keys, '-', '+') Defensive patterns
Strategy: validation
Validate before calling
def safe_nrange(client, keys, frm, to, **kw):
if not keys:
return []
return client.ts().nrange(list(keys), frm, to, **kw) Type guard
def has_keys(keys) -> bool:
return bool(keys) Try / catch
try:
client.ts().nrange(keys, '-', '+')
except Exception as e:
if 'At least one key' in str(e):
result = []
else:
raise Prevention
- Resolve the key list (e.g. via TS.QUERYINDEX) before calling nrange.
- Short-circuit with an empty result when no keys match.
- Validate upstream lookups return keys.
When it happens
Trigger: Calling client.ts().nrange([], '-', '+') or client.ts().nrange(keys, '-', '+') where keys resolved to an empty list; same for nrevrange.
Common situations: Querying a list of keys produced by a label filter/lookup that matched nothing; fan-out from upstream that returned an empty set; defaulting keys to [] and forgetting to populate.
Related errors
- AGGREGATION requires exactly one aggregation spec per key (e
- index_type must be one of {list(IndexType)}
- GROUPBY is not allowed when multiple aggregators are specifi
- EXCLUDEEMPTY is not allowed with GROUPBY
- 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/4721d4afd128b155.json.
Report an issue: GitHub.