sqlalchemy/sqlalchemy · error · ValueError
Operands must be the same length
Error message
Operands must be the same length
What it means
Raised by BitString.__and__ (the bitwise `&` operator) at lib/sqlalchemy/dialects/postgresql/bitstring.py:264-265 when the two operands differ in bit length. Bitwise AND is only defined element-wise, so mismatched lengths are rejected rather than zero-padded. Non-str operands return NotImplemented instead (letting Python try the reflected operator).
Source
Thrown at lib/sqlalchemy/dialects/postgresql/bitstring.py:265
~BitString("01010") == BitString("10101")
"""
return BitString("".join("1" if x == "0" else "0" for x in self))
def __and__(self, o: str) -> BitString:
"""Performs a bitwise and (``&``) with the given operand.
A ``ValueError`` is raised if the operand is not the same length.
e.g.::
BitString("011") & BitString("011") == BitString("010")
"""
if not isinstance(o, str):
return NotImplemented
o = BitString(o)
if len(self) != len(o):
raise ValueError("Operands must be the same length")
return BitString(
"".join(
"1" if (x == "1" and y == "1") else "0"
for x, y in zip(self, o)
),
False,
)
def __or__(self, o: str) -> BitString:
"""Performs a bitwise or (``|``) with the given operand.
A ``ValueError`` is raised if the operand is not the same length.
e.g.::
BitString("011") | BitString("010") == BitString("011")
"""
if not isinstance(o, str):View on GitHub (pinned to d9b44cb731)
Solutions
- Normalize both operands to the same length first, e.g. with zfill(width) or lstrip('0') on both.
- Build masks from the same BitString source/width as the data: mask = BitString.from_int(0b1010, len(data)).
- Validate len(a) == len(b) before the operation and log the mismatch for diagnosis.
Example fix
// before
result = value & BitString('1010') # value is 8 bits
// after
result = value & BitString('1010').zfill(len(value)) Defensive patterns
Strategy: validation
Validate before calling
other_bs = BitString(other) if not isinstance(other, BitString) else other
if len(bs) != len(other_bs):
raise ValueError('Operands must be the same length for &')
result = bs & other_bs Type guard
def same_length(a: BitString, b) -> bool:
return isinstance(b, str) and len(a) == len(BitString(b)) Try / catch
try:
result = bs & other
except ValueError as e:
if 'same length' in str(e):
# pad the shorter operand on the left with zeros
n = max(len(bs), len(BitString(other)))
result = bs.zfill(n) & BitString(other).zfill(n) Prevention
- Normalize operands to a canonical width with zfill(width) before bitwise ops.
- Compare .bit_length on both sides as a precondition.
- Derive both operands from a schema-fixed BIT(n) column so lengths always match.
When it happens
Trigger: BitString('011') & BitString('0110'), or any `&` where len(left) != len(right). Common after lstrip/strip/from_int produce strings of differing width.
Common situations: Combining a BIT(8) column value with a hand-built mask of different width; operands sourced from columns resized at different times; one side came from from_int(length=4) and the other from raw bytes (length=8).
Related errors
- BitString must only contain '0' and '1' chars
- value must be non-negative
- length must be non-negative
- Cannot encode {value} as a BitString of length {length}
- Cannot encode {value!r} as a BitString of length {length}
AI-assisted analysis of sqlalchemy/sqlalchemy@d9b44cb731 (2026-08-01).
Data as JSON: /data/errors/cec09d7dce74cb25.json.
Report an issue: GitHub.