redis/redis-py · error · DataError

bit must be 0 or 1

Error message

bit must be 0 or 1

What it means

bitpos() searches for the first occurrence of a specific bit value, so the bit argument must be exactly 0 or 1. Any other integer (or value) is rejected at core.py:2782 with DataError because Redis has no other bit states to find.

Source

Thrown at redis/commands/core.py:2783

    def bitpos(
        self,
        key: KeyT,
        bit: int,
        start: int | None = None,
        end: int | None = None,
        mode: str | None = None,
    ) -> int | Awaitable[int]:
        """
        Return the position of the first bit set to 1 or 0 in a string.
        ``start`` and ``end`` defines search range. The range is interpreted
        as a range of bytes and not a range of bits, so start=0 and end=2
        means to look at the first three bytes.

        For more information, see https://redis.io/commands/bitpos
        """
        if bit not in (0, 1):
            raise DataError("bit must be 0 or 1")
        params = [key, bit]

        start is not None and params.append(start)

        if start is not None and end is not None:
            params.append(end)
        elif start is None and end is not None:
            raise DataError("start argument is not set, when end is specified")

        if mode is not None:
            params.append(mode)
        return self.execute_command("BITPOS", *params, keys=[key])

    @overload
    def copy(
        self: SyncClientProtocol,
        source: str,
        destination: str,

View on GitHub (pinned to da03cdc7e8)

Solutions

  1. Pass bit=0 or bit=1 explicitly.
  2. Clamp/sanitize external input before calling: bit = 1 if value else 0.
  3. Add a precondition assert or if-check at the call site for clarity.

Example fix

# before
pos = r.bitpos('key', bit=flag)  # flag may be 2

# after
pos = r.bitpos('key', bit=1 if flag else 0)
Defensive patterns

Strategy: validation

Validate before calling

if bit not in (0, 1):
    bit = 1 if bit else 0
r.bitpos('key', bit)

Type guard

def is_valid_bit(bit: int) -> bool:
    return bit in (0, 1)

Try / catch

from redis.exceptions import DataError
try:
    r.bitpos('key', bit)
except DataError as e:
    if 'bit must be 0 or 1' in str(e):
        r.bitpos('key', 1 if bit else 0)
    else:
        raise

Prevention

When it happens

Trigger: r.bitpos('key', 2), r.bitpos('key', bit=-1), or passing a computed/validated value that fell outside {0,1}.

Common situations: Passing a user-supplied or computed flag without clamping to binary; off-by-one in a loop variable fed into bitpos.

Related errors


AI-assisted analysis of redis/redis-py@da03cdc7e8 (2026-08-04). Data as JSON: /data/errors/590d77c341687f84.json. Report an issue: GitHub.