boto/boto3 · error · DynamoDBOperationNotSupportedError
AND operation cannot be applied to value {value} of type {ty
Error message
AND 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.__and__ when the & operator is applied between a ConditionBase (e.g. the result of Attr('x').eq(1)) and an operand that is NOT a ConditionBase. DynamoDB condition expressions can only be combined (&) with other conditions; combining a condition with a raw value, string, dict, or number is invalid because the library cannot build a valid DynamoDB FilterExpression/ConditionExpression from a non-condition.
Source
Thrown at boto3/dynamodb/conditions.py:35
DynamoDBNeedsConditionError,
DynamoDBNeedsKeyConditionError,
DynamoDBOperationNotSupportedError,
)
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):View on GitHub (pinned to c7b4afac23)
Solutions
- Ensure BOTH operands of & are ConditionBase instances, e.g. Attr('status').eq('active') & Attr('pending').eq(True).
- Check the right-hand operand with isinstance(other, ConditionBase) before combining.
- Chain conditions incrementally and assert each intermediate result is a condition.
Example fix
# before
fe = Attr('status').eq('active') & 'pending'
table.scan(FilterExpression=fe)
# after
fe = Attr('status').eq('active') & Attr('status').eq('pending')
table.scan(FilterExpression=fe) Defensive patterns
Strategy: type-guard
Validate before calling
from boto3.dynamodb.conditions import ConditionBase
def safe_and(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:
# other was not a condition; build a proper condition instead
expr = cond_a & Attr('field').eq(other) Prevention
- Always call a comparison method (.eq, .gt, .begins_with, ...) on every Attr/Key before combining.
- Lint DynamoDB filter expressions with isinstance checks during development.
- Keep conditions as named variables so partial constructions are visible.
When it happens
Trigger: table.scan(FilterExpression=Attr('status').eq('active') & 'pending') — the right operand 'pending' is a str, not a ConditionBase. Also Attr('n').eq(1) & 2 or Attr('n').eq(1) & {'x': 1}.
Common situations: Forgetting to call .eq()/.gt()/.begins_with() on the second attribute operand; accidentally short-circuiting with a literal; copy-paste where one side of the & was truncated.
Related errors
- OR operation cannot be applied to value {value} of type {typ
- 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/1c013aeff2251ee0.json.
Report an issue: GitHub.