redis/redis-py · error · DataError
block_min_count requires block_milliseconds to be set; the…
Error message
block_min_count requires block_milliseconds to be set; the BLOCK group is all-or-nothing.
What it means
Raised by _append_block (used by TS.RANGE/XRANGE-style blocking reads) when block_min_count is set but block_milliseconds is None. The BLOCK clause is all-or-nothing on the wire: blocking requires the milliseconds value, and min_count alone is not a valid standalone keyword.
Solutions
- Always set block_milliseconds when you set block_min_count.
- If you do not want blocking, omit both block_milliseconds and block_min_count.
- Validate the pair together in your wrapper before calling the API.
Example fix
// before
client.ts().range(key, f, t,
block_milliseconds=None, block_min_count=5)
// after
client.ts().range(key, f, t,
block_milliseconds=1000, block_min_count=5)
# or non-blocking: omit both Defensive patterns
Strategy: validation
Validate before calling
if block_min_count is not None and block_milliseconds is None:
raise ValueError('block_milliseconds required when block_min_count is set')
client.ts().range(key, f, t, block_milliseconds=block_milliseconds, block_min_count=block_min_count) Try / catch
from redis.exceptions import DataError
try:
client.ts().range(key, f, t, block_milliseconds=block_milliseconds, block_min_count=block_min_count)
except DataError:
client.ts().range(key, f, t) # fall back to non-blocking Prevention
- Treat block_milliseconds and block_min_count as a single optional pair.
- Validate the pair together in config loaders.
When it happens
Trigger: Calling a range read with block_min_count=5 but block_milliseconds=None (omitted). Passing only the min_count half of a blocking pair.
Common situations: Config objects that map block_min_count without block_milliseconds. Partial migration where one parameter was renamed or dropped.
Related errors
- AGGREGATION requires exactly one aggregation spec per key
- At least one key must be provided.
- Both ignore_max_time_diff and ignore_max_val_diff must be…
- EXCLUDEEMPTY is not allowed with GROUPBY
- filters cannot be an empty collection; pass None to query…
AI-assisted analysis of redis/redis-py@6a6b581b48 (2026-08-10).
Data as JSON: /api/errors/a52eef52d1e94e6d.
Report an issue: GitHub.
Appendix: source
Thrown at redis/commands/timeseries/commands.py:1999
if count is not None:
params.extend(["COUNT", count])
@staticmethod
def _append_block(
params: list[EncodableT],
block_milliseconds: int | None,
block_min_count: int | None,
):
"""Append the BLOCK group to params.
The BLOCK group is all-or-nothing: when blocking is requested
(`block_milliseconds` is set), both `milliseconds` and `min_count` are
always emitted, with `min_count` defaulting to 1. There is no standalone
MIN_COUNT keyword in this command.
"""
if block_milliseconds is None:
if block_min_count is not None:
raise DataError(
"block_min_count requires block_milliseconds to be set; the "
"BLOCK group is all-or-nothing."
)
return
min_count = 1 if block_min_count is None else block_min_count
params.extend(["BLOCK", block_milliseconds, min_count])
@staticmethod
def _append_max_count(params: list[EncodableT], max_count: int | None):
"""Append MAX_COUNT property to params."""
if max_count is not None:
params.extend(["MAX_COUNT", max_count])
@staticmethod
def _append_timestamp(params: list[EncodableT], timestamp: int | None):
"""Append TIMESTAMP property to params."""
if timestamp is not None:
params.extend(["TIMESTAMP", timestamp])View on GitHub (pinned to 6a6b581b48)