{"id":"cec09d7dce74cb25","repo":"sqlalchemy/sqlalchemy","slug":"operands-must-be-the-same-length","errorCode":null,"errorMessage":"Operands must be the same length","messagePattern":"Operands must be the same length","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"lib/sqlalchemy/dialects/postgresql/bitstring.py","lineNumber":265,"sourceCode":"\n            ~BitString(\"01010\") == BitString(\"10101\")\n        \"\"\"\n        return BitString(\"\".join(\"1\" if x == \"0\" else \"0\" for x in self))\n\n    def __and__(self, o: str) -> BitString:\n        \"\"\"Performs a bitwise and (``&``) with the given operand.\n        A ``ValueError`` is raised if the operand is not the same length.\n\n        e.g.::\n\n            BitString(\"011\") & BitString(\"011\") == BitString(\"010\")\n        \"\"\"\n\n        if not isinstance(o, str):\n            return NotImplemented\n        o = BitString(o)\n        if len(self) != len(o):\n            raise ValueError(\"Operands must be the same length\")\n\n        return BitString(\n            \"\".join(\n                \"1\" if (x == \"1\" and y == \"1\") else \"0\"\n                for x, y in zip(self, o)\n            ),\n            False,\n        )\n\n    def __or__(self, o: str) -> BitString:\n        \"\"\"Performs a bitwise or (``|``) with the given operand.\n        A ``ValueError`` is raised if the operand is not the same length.\n\n        e.g.::\n\n            BitString(\"011\") | BitString(\"010\") == BitString(\"011\")\n        \"\"\"\n        if not isinstance(o, str):","sourceCodeStart":247,"sourceCodeEnd":283,"githubUrl":"https://github.com/sqlalchemy/sqlalchemy/blob/d9b44cb731bd27e6e82c99a3c0fb598214e8e7ff/lib/sqlalchemy/dialects/postgresql/bitstring.py#L247-L283","documentation":"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).","triggerScenarios":"BitString('011') & BitString('0110'), or any `&` where len(left) != len(right). Common after lstrip/strip/from_int produce strings of differing width.","commonSituations":"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).","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."],"exampleFix":"// before\nresult = value & BitString('1010')  # value is 8 bits\n// after\nresult = value & BitString('1010').zfill(len(value))","handlingStrategy":"validation","validationCode":"other_bs = BitString(other) if not isinstance(other, BitString) else other\nif len(bs) != len(other_bs):\n    raise ValueError('Operands must be the same length for &')\nresult = bs & other_bs","typeGuard":"def same_length(a: BitString, b) -> bool:\n    return isinstance(b, str) and len(a) == len(BitString(b))","tryCatchPattern":"try:\n    result = bs & other\nexcept ValueError as e:\n    if 'same length' in str(e):\n        # pad the shorter operand on the left with zeros\n        n = max(len(bs), len(BitString(other)))\n        result = bs.zfill(n) & BitString(other).zfill(n)","preventionTips":["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."],"tags":["bitstring","valueerror","operator-overloading","postgresql"],"analyzedSha":"d9b44cb731bd27e6e82c99a3c0fb598214e8e7ff","analyzedAt":"2026-08-01T17:20:52.075Z","schemaVersion":2}