redis/redis-py · error · DataError

Both start and end must be specified

Error message

Both start and end must be specified

What it means

Raised as a `DataError` by `bitcount()` (redis/commands/core.py:2667) when exactly one of `start`/`end` is provided. BITCOUNT's range is defined by a (start, end) pair, so the client refuses to send a partial range.

Solutions

  1. Supply both `start` and `end` together, e.g. `r.bitcount('k', start=0, end=-1)`.
  2. Omit both to count over the whole string.
  3. Centralize range construction so partial ranges never reach the call.

Example fix

// before
r.bitcount('k', start=0)
// after
r.bitcount('k', start=0, end=-1)  # whole string in byte mode
Defensive patterns

Strategy: validation

Validate before calling

if (start is None) != (end is None):
    raise ValueError('bitcount: set both start and end, or neither')
r.bitcount('k', start=start, end=end)

Prevention

When it happens

Trigger: `r.bitcount('k', start=0)`, `r.bitcount('k', end=10)`, or any call where one positional/keyword boundary is `None` and the other is an int.

Common situations: Passing `end` as a keyword while forgetting `start`; building ranges dynamically where one bound computes to `None` under some branch; off-by-one reasoning where the developer assumed a default for the missing bound.

Related errors


AI-assisted analysis of redis/redis-py@6a6b581b48 (2026-08-10). Data as JSON: /api/errors/fdd904a9d7fe3b9a. Report an issue: GitHub.

Appendix: 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)

    @overload

View on GitHub (pinned to 6a6b581b48)