{"id":"a235c6851b5442ae","repo":"boto/boto3","slug":"float-types-are-not-supported-use-decimal-types-i","errorCode":null,"errorMessage":"Float types are not supported. Use Decimal types instead.","messagePattern":"Float types are not supported\\. Use Decimal types instead\\.","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"boto3/dynamodb/types.py","lineNumber":171,"sourceCode":"            raise TypeError(msg)\n\n        return dynamodb_type\n\n    def _is_null(self, value):\n        if value is None:\n            return True\n        return False\n\n    def _is_boolean(self, value):\n        if isinstance(value, bool):\n            return True\n        return False\n\n    def _is_number(self, value):\n        if isinstance(value, (int, Decimal)):\n            return True\n        elif isinstance(value, float):\n            raise TypeError(\n                'Float types are not supported. Use Decimal types instead.'\n            )\n        return False\n\n    def _is_string(self, value):\n        if isinstance(value, str):\n            return True\n        return False\n\n    def _is_binary(self, value):\n        if isinstance(value, (Binary, bytearray, bytes)):\n            return True\n        return False\n\n    def _is_set(self, value):\n        if isinstance(value, collections_abc.Set):\n            return True\n        return False","sourceCodeStart":153,"sourceCodeEnd":189,"githubUrl":"https://github.com/boto/boto3/blob/c7b4afac237b976d48395d7523eaf7cec3a450b3/boto3/dynamodb/types.py#L153-L189","documentation":"Raised by TypeSerializer._is_number when the value is a float. DynamoDB numbers have arbitrary precision (up to 38 digits) which Python float cannot represent exactly, so boto3 rejects floats outright and requires the decimal.Decimal type. This fires before the generic 'Unsupported type' error because _is_number checks isinstance(value, float) explicitly.","triggerScenarios":"table.put_item(Item={'price': 9.99}) — 9.99 is a float. Also serialize(3.14), or a set containing floats like {1.0, 2.0} (fails _is_type_set for number because _is_number raises on each float).","commonSituations":"Loading JSON with json.load (which produces floats for decimal numbers) and passing directly to DynamoDB; computing averages or currency as floats; migrating from an ORM that emits floats.","solutions":["Use Decimal(str(float_value)) to convert: Decimal(str(9.99)).","Parse JSON with parse_float=Decimal: json.loads(data, parse_float=Decimal).","Use Decimal literals directly: Decimal('9.99')."],"exampleFix":"# before\ntable.put_item(Item={'price': 9.99})\n\n# after\nfrom decimal import Decimal\ntable.put_item(Item={'price': Decimal('9.99')})\n# or when loading from JSON\nimport json\nfrom decimal import Decimal\ndata = json.loads(raw, parse_float=Decimal)","handlingStrategy":"validation","validationCode":"from decimal import Decimal\n\ndef to_dynamodb_number(value):\n    if isinstance(value, float):\n        return Decimal(str(value))\n    return value\n\ndef normalize_item(item):\n    return {k: to_dynamodb_number(v) if isinstance(v, (int, float)) else v for k, v in item.items()}\n\n# For JSON parsing:\n# json.loads(raw_text, parse_float=Decimal)","typeGuard":"from decimal import Decimal\n\ndef is_dynamodb_number(v) -> bool:\n    return isinstance(v, (int, Decimal)) and not isinstance(v, bool)","tryCatchPattern":null,"preventionTips":["Always parse JSON destined for DynamoDB with parse_float=Decimal.","Use Decimal literals for money, measurements, and any value needing exact representation.","Add a pre-write normalizer that converts every float in the Item to Decimal(str(...))."],"tags":["dynamodb","types","float","decimal","serialization"],"analyzedSha":"c7b4afac237b976d48395d7523eaf7cec3a450b3","analyzedAt":"2026-08-04T20:35:51.598Z","schemaVersion":2}