boto/boto3 · error · TypeError
Float types are not supported. Use Decimal types instead.
Error message
Float types are not supported. Use Decimal types instead.
What it means
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.
Source
Thrown at boto3/dynamodb/types.py:171
raise TypeError(msg)
return dynamodb_type
def _is_null(self, value):
if value is None:
return True
return False
def _is_boolean(self, value):
if isinstance(value, bool):
return True
return False
def _is_number(self, value):
if isinstance(value, (int, Decimal)):
return True
elif isinstance(value, float):
raise TypeError(
'Float types are not supported. Use Decimal types instead.'
)
return False
def _is_string(self, value):
if isinstance(value, str):
return True
return False
def _is_binary(self, value):
if isinstance(value, (Binary, bytearray, bytes)):
return True
return False
def _is_set(self, value):
if isinstance(value, collections_abc.Set):
return True
return FalseView on GitHub (pinned to c7b4afac23)
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').
Example fix
# before
table.put_item(Item={'price': 9.99})
# after
from decimal import Decimal
table.put_item(Item={'price': Decimal('9.99')})
# or when loading from JSON
import json
from decimal import Decimal
data = json.loads(raw, parse_float=Decimal) Defensive patterns
Strategy: validation
Validate before calling
from decimal import Decimal
def to_dynamodb_number(value):
if isinstance(value, float):
return Decimal(str(value))
return value
def normalize_item(item):
return {k: to_dynamodb_number(v) if isinstance(v, (int, float)) else v for k, v in item.items()}
# For JSON parsing:
# json.loads(raw_text, parse_float=Decimal) Type guard
from decimal import Decimal
def is_dynamodb_number(v) -> bool:
return isinstance(v, (int, Decimal)) and not isinstance(v, bool) Prevention
- 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(...)).
When it happens
Trigger: 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).
Common situations: 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.
Related errors
- Infinity and NaN not supported
- Value must be of the following types: {types}
- Unsupported type "{type(value)}" for value "{value}"
- Value must be a nonempty dictionary whose key is a valid dyn
- Dynamodb type {dynamodb_type} is not supported
AI-assisted analysis of boto/boto3@c7b4afac23 (2026-08-04).
Data as JSON: /data/errors/a235c6851b5442ae.json.
Report an issue: GitHub.