boto/boto3 · error · DynamoDBOperationNotSupportedError
OR operation cannot be applied to value {value} of type {typ
Error message
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. What it means
Raised by ConditionBase.__or__ when the | operator is applied between a ConditionBase and an operand that is not a ConditionBase. Same principle as the AND variant: OR in DynamoDB condition expressions requires both sides to be conditions so the library can emit a valid OR node in the expression tree.
Source
Thrown at boto3/dynamodb/conditions.py:40
ATTR_NAME_REGEX = re.compile(r'[^.\[\]]+(?![^\[]*\])')
class ConditionBase:
expression_format = ''
expression_operator = ''
has_grouped_values = False
def __init__(self, *values):
self._values = values
def __and__(self, other):
if not isinstance(other, ConditionBase):
raise DynamoDBOperationNotSupportedError('AND', other)
return And(self, other)
def __or__(self, other):
if not isinstance(other, ConditionBase):
raise DynamoDBOperationNotSupportedError('OR', other)
return Or(self, other)
def __invert__(self):
return Not(self)
def get_expression(self):
return {
'format': self.expression_format,
'operator': self.expression_operator,
'values': self._values,
}
def __eq__(self, other):
if isinstance(other, type(self)):
if self._values == other._values:
return True
return False
View on GitHub (pinned to c7b4afac23)
Solutions
- Make the right operand a ConditionBase: Attr('status').eq('active') | Attr('status').eq('archived').
- Validate with isinstance(right, ConditionBase) before |.
- Use Attr(...).is_in([...]) when OR-ing equality on the same attribute.
Example fix
# before
fe = Attr('status').eq('active') | 'archived'
# after
fe = Attr('status').eq('active') | Attr('status').eq('archived')
# or equivalently
fe = Attr('status').is_in(['active', 'archived']) Defensive patterns
Strategy: type-guard
Validate before calling
from boto3.dynamodb.conditions import ConditionBase
def safe_or(left, right):
if not isinstance(right, ConditionBase):
raise TypeError(f'Right operand of | must be a ConditionBase, got {type(right)}')
return left | right Type guard
from boto3.dynamodb.conditions import ConditionBase
def is_condition(v) -> bool:
return isinstance(v, ConditionBase) Try / catch
from boto3.exceptions import DynamoDBOperationNotSupportedError
try:
expr = cond_a | other
except DynamoDBOperationNotSupportedError:
expr = cond_a | Attr('field').eq(other) Prevention
- Use Attr(...).is_in([...]) instead of chaining multiple | when OR-ing equality checks.
- Verify every operand in a compound expression is a ConditionBase.
- Name each sub-condition so a truncated operand is obvious.
When it happens
Trigger: table.scan(FilterExpression=Attr('status').eq('active') | 'archived') — the right operand is a bare string. Also Attr('n').eq(1) | 5 or any | with a non-ConditionBase.
Common situations: Mixing up OR with attribute_exists/attribute_not_exists shorthand; forgetting .eq() on the second side; treating | like a bitwise OR on values.
Related errors
- AND operation cannot be applied to value {value} of type {ty
- NOT operation cannot be applied to value {value} of type {ty
- Expecting a ConditionBase object. Got {value} of type {type(
- Attribute object {value.name} is of type {type(value)}. KeyC
- Value must be of the following types: {types}
AI-assisted analysis of boto/boto3@c7b4afac23 (2026-08-04).
Data as JSON: /data/errors/da5edcc0e659b018.json.
Report an issue: GitHub.