{"record":{"id":"da5edcc0e659b018","repo":"boto/boto3","slug":"or-operation-cannot-be-applied-to-value-value-of","errorCode":null,"errorMessage":"OR operation cannot be applied to value {value} of type {type(value)} directly. Must use AttributeBase object methods (i.e. Attr().eq()). to generate ConditionBase instances first.","messagePattern":"OR operation cannot be applied to value (.+?) of type (.+?) directly\\. Must use AttributeBase object methods \\(i\\.e\\. Attr\\(\\)\\.eq\\(\\)\\)\\. to generate ConditionBase instances first\\.","errorType":"exception","errorClass":"DynamoDBOperationNotSupportedError","httpStatus":null,"severity":"error","filePath":"boto3/dynamodb/conditions.py","lineNumber":40,"sourceCode":"ATTR_NAME_REGEX = re.compile(r'[^.\\[\\]]+(?![^\\[]*\\])')\n\n\nclass ConditionBase:\n    expression_format = ''\n    expression_operator = ''\n    has_grouped_values = False\n\n    def __init__(self, *values):\n        self._values = values\n\n    def __and__(self, other):\n        if not isinstance(other, ConditionBase):\n            raise DynamoDBOperationNotSupportedError('AND', other)\n        return And(self, other)\n\n    def __or__(self, other):\n        if not isinstance(other, ConditionBase):\n            raise DynamoDBOperationNotSupportedError('OR', other)\n        return Or(self, other)\n\n    def __invert__(self):\n        return Not(self)\n\n    def get_expression(self):\n        return {\n            'format': self.expression_format,\n            'operator': self.expression_operator,\n            'values': self._values,\n        }\n\n    def __eq__(self, other):\n        if isinstance(other, type(self)):\n            if self._values == other._values:\n                return True\n        return False\n","sourceCodeStart":22,"sourceCodeEnd":58,"githubUrl":"https://github.com/boto/boto3/blob/6e10b029c1326a437932a8b24f38af69fd986e15/boto3/dynamodb/conditions.py#L22-L58","documentation":"Symmetric to the AND case: the | operator is defined on ConditionBase and only accepts another ConditionBase. Applying | with a non-ConditionBase raises DynamoDBOperationNotSupportedError('OR', other), because DynamoDB OR semantics only exist between condition expressions, not between an expression and a raw value.","triggerScenarios":"Key('pk').eq('a') | 'b', Attr('flag').eq(1) | [1,2,3], or any | where one side is a literal/None/str instead of a ConditionBase.","commonSituations":"Trying to express 'attribute equals any of these values' with | instead of Attr(...).is_in([...]); building OR chains from user input where one input is missing.","solutions":["Use Attr(name).is_in([...]) for value-set membership instead of OR-ing scalar literals.","Verify every operand of | is a ConditionBase before applying it.","Filter out None/empty operands when constructing OR chains dynamically."],"exampleFix":"# before\nexpr = Attr('role').eq('admin') | 'user' | 'guest'\n# after\nexpr = Attr('role').is_in(['admin', 'user', 'guest'])","handlingStrategy":"type-guard","validationCode":"from boto3.dynamodb.conditions import ConditionBase\noperands = [a, b, c]\nassert all(isinstance(o, ConditionBase) for o in operands), \\\n    'OR operands must be ConditionBase; use Attr(name).is_in([...]) for value sets'","typeGuard":"from boto3.dynamodb.conditions import ConditionBase\ndef all_conditions(values):\n    return all(isinstance(v, ConditionBase) for v in values)","tryCatchPattern":"from boto3.exceptions import DynamoDBOperationNotSupportedError\ntry:\n    expr = base | extra\nexcept DynamoDBOperationNotSupportedError:\n    # fallback to a membership check\n    expr = Attr('role').is_in(['a', 'b'])","preventionTips":["Prefer Attr(...).is_in([...]) over OR chains for value membership.","Type-check OR operands when assembling from user input.","Skip None operands explicitly rather than OR-ing them."],"tags":["dynamodb","conditions","expression","boto3"],"backgroundTag":null,"analyzedSha":"6e10b029c1326a437932a8b24f38af69fd986e15","analyzedAt":"2026-08-11T20:52:47.213Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}