boto/boto3 · error · DynamoDBNeedsConditionError
Expecting a ConditionBase object. Got {value} of type {type(
Error message
Expecting a ConditionBase object. Got {value} of type {type(value)}. Use AttributeBase object methods (i.e. Attr().eq()). to generate ConditionBase instances. What it means
Raised by ConditionExpressionBuilder.build_expression() when the object passed as a condition is not a ConditionBase. The builder recurses through the condition tree emitting placeholders; a non-condition (raw value, bare Attr/Key, or unrelated object) cannot be processed. This is typically surfaced when a table.query / table.scan / item.update receives a FilterExpression, ConditionExpression, or KeyConditionExpression that is not a fully-built condition.
Source
Thrown at boto3/dynamodb/conditions.py:344
:type condition: ConditionBase
:param condition: A condition to be built into a condition expression
string with any necessary placeholders.
:type is_key_condition: Boolean
:param is_key_condition: True if the expression is for a
KeyConditionExpression. False otherwise.
:rtype: (string, dict, dict)
:returns: Will return a string representing the condition with
placeholders inserted where necessary, a dictionary of
placeholders for attribute names, and a dictionary of
placeholders for attribute values. Here is a sample return value:
('#n0 = :v0', {'#n0': 'myattribute'}, {':v1': 'myvalue'})
"""
if not isinstance(condition, ConditionBase):
raise DynamoDBNeedsConditionError(condition)
attribute_name_placeholders = {}
attribute_value_placeholders = {}
condition_expression = self._build_expression(
condition,
attribute_name_placeholders,
attribute_value_placeholders,
is_key_condition=is_key_condition,
)
return BuiltConditionExpression(
condition_expression=condition_expression,
attribute_name_placeholders=attribute_name_placeholders,
attribute_value_placeholders=attribute_value_placeholders,
)
def _build_expression(
self,
condition,
attribute_name_placeholders,View on GitHub (pinned to c7b4afac23)
Solutions
- Ensure the expression is a ConditionBase: table.query(KeyConditionExpression=Key('pk').eq('v')).
- For filter expressions, call a comparison/method on Attr: Attr('x').eq(1) or Attr('x').exists().
- If you must build from strings, use raw KeyConditionExpression strings with explicit placeholders instead of the builder.
Example fix
# before
table.query(KeyConditionExpression=Key('pk'))
# after
table.query(KeyConditionExpression=Key('pk').eq('user#1')) Defensive patterns
Strategy: type-guard
Validate before calling
from boto3.dynamodb.conditions import ConditionBase
def check_expression(expr):
if not isinstance(expr, ConditionBase):
raise TypeError(f'Expected ConditionBase, got {type(expr).__name__}')
return expr Type guard
from boto3.dynamodb.conditions import ConditionBase
def is_condition(v) -> bool:
return isinstance(v, ConditionBase) Try / catch
from boto3.exceptions import DynamoDBNeedsConditionError
try:
table.scan(FilterExpression=expr)
except DynamoDBNeedsConditionError:
# expr was not a built condition; rebuild it
table.scan(FilterExpression=Attr('x').eq(expr)) Prevention
- Always terminate Key()/Attr() chains with a comparison or function method.
- Wrap expression construction in a helper that asserts isinstance(..., ConditionBase).
- Write unit tests for DynamoDB query/scan calls so malformed expressions fail early.
When it happens
Trigger: table.query(KeyConditionExpression=Key('pk')) — missing .eq()/.begins_with(); table.scan(FilterExpression=Attr('x')) — bare Attr; passing a plain dict or string to FilterExpression.
Common situations: Forgetting the terminal comparison method on Key/Attr; passing a raw attribute name string instead of a condition object; refactoring that drops the final method call.
Related errors
- AND operation cannot be applied to value {value} of type {ty
- OR operation cannot be applied to value {value} of type {typ
- NOT operation cannot be applied to value {value} of type {ty
- 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/99c4ca6cb38bbd48.json.
Report an issue: GitHub.