redis/redis-py · error · DataError
Both start and end must be specified
Error message
Both start and end must be specified
What it means
bitcount() requires start and end to be supplied together or both omitted; specifying only one is ambiguous (Redis BITCOUNT needs a closed range). The guard at core.py:2667 rejects the half-specified range with DataError before sending a malformed command.
Source
Thrown at redis/commands/core.py:2668
def bitcount(
self,
key: KeyT,
start: int | None = None,
end: int | None = None,
mode: str | None = None,
) -> int | Awaitable[int]:
"""
Returns the count of set bits in the value of ``key``. Optional
``start`` and ``end`` parameters indicate which bytes to consider
For more information, see https://redis.io/commands/bitcount
"""
params = [key]
if start is not None and end is not None:
params.append(start)
params.append(end)
elif (start is not None and end is None) or (end is not None and start is None):
raise DataError("Both start and end must be specified")
if mode is not None:
params.append(mode)
return self.execute_command("BITCOUNT", *params, keys=[key])
def bitfield(
self: Union["redis.client.Redis", "redis.asyncio.client.Redis"],
key: KeyT,
default_overflow: str | None = None,
) -> BitFieldOperation:
"""
Return a BitFieldOperation instance to conveniently construct one or
more bitfield operations on ``key``.
For more information, see https://redis.io/commands/bitfield
"""
return BitFieldOperation(self, key, default_overflow=default_overflow)
@overloadView on GitHub (pinned to da03cdc7e8)
Solutions
- Pass both start and end as a pair, e.g. r.bitcount('key', start=0, end=10).
- Omit both to count over the whole string, e.g. r.bitcount('key').
- When building params dynamically, default the missing bound explicitly (start=0 when only end is given, end=-1 when only start is given).
Example fix
# before
r.bitcount('key', start=0)
# after
r.bitcount('key', start=0, end=10) Defensive patterns
Strategy: validation
Validate before calling
if (start is None) != (end is None):
raise ValueError('bitcount: provide both start and end, or neither')
r.bitcount('key', start=start, end=end) Type guard
def valid_bitcount_range(start, end) -> bool:
return (start is None) == (end is None) Try / catch
from redis.exceptions import DataError
try:
r.bitcount('key', start=start, end=end)
except DataError as e:
if 'Both start and end' in str(e):
end = -1 if end is None else end
start = 0 if start is None else start
r.bitcount('key', start=start, end=end)
else:
raise Prevention
- Always pass start and end as a tuple/pair from a single config source.
- Use r.bitcount('key') with no range when you want the whole string.
When it happens
Trigger: r.bitcount('key', start=0) with no end, or r.bitcount('key', end=10) with no start. Both trigger the XOR branch in the elif.
Common situations: Dynamically building kwargs from optional CLI flags or config where only one bound was populated; refactoring from an older API that defaulted the missing bound.
Related errors
- start argument is not set, when end is specified
- Only one of IFEQ/IFNE/IFDEQ/IFDNE may be specified
- ``ex``, ``px``, ``exat``, ``pxat``, and ``persist`` are mutu
- ``byfloat`` and ``byint`` are mutually exclusive.
- ``count`` is required when ``mode`` or ``ordering`` is set
AI-assisted analysis of redis/redis-py@da03cdc7e8 (2026-08-04).
Data as JSON: /data/errors/fdd904a9d7fe3b9a.json.
Report an issue: GitHub.