{"id":"b224280c78a2f066","repo":"boto/boto3","slug":"not-operation-cannot-be-applied-to-value-value-o","errorCode":null,"errorMessage":"NOT 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":"NOT 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":74,"sourceCode":"                return True\n        return False\n\n    def __ne__(self, other):\n        return not self.__eq__(other)\n\n\nclass AttributeBase:\n    def __init__(self, name):\n        self.name = name\n\n    def __and__(self, value):\n        raise DynamoDBOperationNotSupportedError('AND', self)\n\n    def __or__(self, value):\n        raise DynamoDBOperationNotSupportedError('OR', self)\n\n    def __invert__(self):\n        raise DynamoDBOperationNotSupportedError('NOT', self)\n\n    def eq(self, value):\n        \"\"\"Creates a condition where the attribute is equal to the value.\n\n        :param value: The value that the attribute is equal to.\n        \"\"\"\n        return Equals(self, value)\n\n    def lt(self, value):\n        \"\"\"Creates a condition where the attribute is less than the value.\n\n        :param value: The value that the attribute is less than.\n        \"\"\"\n        return LessThan(self, value)\n\n    def lte(self, value):\n        \"\"\"Creates a condition where the attribute is less than or equal to the\n           value.","sourceCodeStart":56,"sourceCodeEnd":92,"githubUrl":"https://github.com/boto/boto3/blob/c7b4afac237b976d48395d7523eaf7cec3a450b3/boto3/dynamodb/conditions.py#L56-L92","documentation":"Raised by AttributeBase.__invert__ (~) when the unary NOT operator is applied to a bare Attr/Key that has not been turned into a ConditionBase. You cannot negate a raw attribute; you must first build a condition (e.g. Attr('x').eq(1)) and then negate that condition with ~.","triggerScenarios":"table.scan(FilterExpression=~Attr('x')) — no comparison method called. Also ~Key('pk') or ~Attr('x').","commonSituations":"Trying to express 'NOT x' (attribute does not exist) but using ~Attr instead of Attr('x').not_exists(); translating logical NOT naively.","solutions":["Call a comparison method before ~: ~(Attr('x').eq(1)).","For 'attribute does not exist' use Attr('x').not_exists() directly (no ~ needed).","Remember that ~ negates a ConditionBase, not an AttributeBase."],"exampleFix":"# before\nfe = ~Attr('x')\n\n# after (negate a condition)\nfe = ~Attr('x').eq(1)\n# or, if intent was 'attribute does not exist'\nfe = Attr('x').not_exists()","handlingStrategy":"type-guard","validationCode":"from boto3.dynamodb.conditions import ConditionBase, AttributeBase\n\ndef safe_not(item):\n    if isinstance(item, AttributeBase) and not isinstance(item, ConditionBase):\n        raise TypeError(f'Cannot apply ~ to bare Attr/Key {item.name!r}; call a comparison method first')\n    return ~item","typeGuard":"from boto3.dynamodb.conditions import ConditionBase\n\ndef is_built_condition(v) -> bool:\n    return isinstance(v, ConditionBase)","tryCatchPattern":"from boto3.exceptions import DynamoDBOperationNotSupportedError\ntry:\n    fe = ~attr_x\nexcept DynamoDBOperationNotSupportedError:\n    fe = ~attr_x.eq(1)","preventionTips":["Use Attr('x').not_exists() / .exists() for existence checks instead of ~Attr.","Never place ~ directly before Attr()/Key() — always before a complete condition."],"tags":["dynamodb","conditions","filter-expression","operator","attribute-base","not"],"analyzedSha":"c7b4afac237b976d48395d7523eaf7cec3a450b3","analyzedAt":"2026-08-04T20:35:51.598Z","schemaVersion":2}