{"record":{"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/6e10b029c1326a437932a8b24f38af69fd986e15/boto3/dynamodb/conditions.py#L56-L92","documentation":"AttributeBase.__invert__ raises DynamoDBOperationNotSupportedError('NOT', self) so that ~Attr('x') does not silently produce a bitwise complement. NOT is only defined on a ConditionBase; inverting a bare attribute is meaningless because there is no condition to negate.","triggerScenarios":"~Attr('flag'), ~Key('pk'), or any unary ~ applied to a raw AttributeBase instead of to a ConditionBase.","commonSituations":"Expecting ~ to mean 'attribute does not exist' or 'attribute is absent'; refactoring and stripping a comparison method while leaving the ~ operator.","solutions":["Apply ~ to a ConditionBase: ~Attr('flag').eq(True).","For 'attribute does not exist', use ~Attr('flag').exists() or Attr('flag').not_exists().","Ensure the operand of ~ is the return value of an Attr()/Key() comparison method."],"exampleFix":"# before\nexpr = ~Attr('deleted')\n# after\nexpr = ~Attr('deleted').eq(True)\n# or\nexpr = Attr('deleted').not_exists()","handlingStrategy":"validation","validationCode":"from boto3.dynamodb.conditions import ConditionBase\ndef safe_not(c):\n    assert isinstance(c, ConditionBase), 'Apply ~ to a ConditionBase, not a bare attribute'\n    return ~c","typeGuard":"from boto3.dynamodb.conditions import ConditionBase\ndef is_negatable(v) -> bool:\n    return isinstance(v, ConditionBase)","tryCatchPattern":"from boto3.exceptions import DynamoDBOperationNotSupportedError\ntry:\n    expr = ~attr\nexcept DynamoDBOperationNotSupportedError:\n    expr = ~attr.eq(True)","preventionTips":["Apply ~ only to the output of a comparison method.","For 'attribute absent', prefer Attr(name).not_exists().","Lint for '~ Attr(' / '~ Key(' patterns."],"tags":["dynamodb","conditions","attribute","boto3"],"backgroundTag":null,"analyzedSha":"6e10b029c1326a437932a8b24f38af69fd986e15","analyzedAt":"2026-08-11T20:52:47.213Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}