boto/boto3 · error · TypeError
Value must be a nonempty dictionary whose key is a valid…
Error message
Value must be a nonempty dictionary whose key is a valid dynamodb type.
What it means
TypeDeserializer.deserialize expects a nonempty dict shaped like {'S': ...}, {'N': ...}, etc. The first check 'if not value' catches None, {}, and other falsy inputs and raises TypeError, because an empty dictionary gives no type key to dispatch on.
Solutions
- Skip or default None/empty dict inputs before calling deserialize.
- Validate that the value is a dict with exactly one key that is a known DynamoDB type tag.
- Build a small helper that returns None for empty/None payloads instead of forwarding them.
Example fix
# before
d = TypeDeserializer()
val = d.deserialize({})
# after
d = TypeDeserializer()
raw = {}
val = d.deserialize(raw) if raw else None Defensive patterns
Strategy: validation
Validate before calling
VALID = {'S','N','B','SS','NS','BS','BOOL','NULL','L','M'}
def safe_deserialize(d, TypeDeserializer):
if not isinstance(d, dict) or not d:
return None
assert set(d).issubset(VALID), f'unexpected type tags: {set(d) - VALID}'
return TypeDeserializer().deserialize(d) Type guard
VALID = {'S','N','B','SS','NS','BS','BOOL','NULL','L','M'}
def is_dynamo_value(v) -> bool:
return isinstance(v, dict) and len(v) == 1 and next(iter(v)) in VALID Try / catch
from boto3.dynamodb.types import TypeDeserializer
d = TypeDeserializer()
try:
val = d.deserialize(raw)
except TypeError:
val = None Prevention
- Skip empty/None payloads before deserialize.
- Validate single-key dict shape at integration boundaries.
- Prefer the high-level resource API which deserializes for you.
When it happens
Trigger: Calling TypeDeserializer().deserialize({}) or deserialize(None); receiving a malformed attribute value from a non-AWS source or a hand-built dict where the value was popped.
Common situations: Iterating over item attributes and accidentally passing an empty dict; integrating DynamoDB Streams data that has been filtered; testing with placeholder empty values.
Related errors
- Dynamodb type is not supported
- Float types are not supported. Use Decimal types instead.
- Infinity and NaN not supported
- Unsupported type " " for value
- Value must be of the following types
AI-assisted analysis of boto/boto3@6e10b029c1 (2026-08-11).
Data as JSON: /api/errors/3614ab5464d8d4ae.
Report an issue: GitHub.
Appendix: source
Thrown at boto3/dynamodb/types.py:269
DynamoDB Python
-------- ------
{'NULL': True} None
{'BOOL': True/False} True/False
{'N': str(value)} Decimal(str(value))
{'S': string} string
{'B': bytes} Binary(bytes)
{'NS': [str(value)]} set([Decimal(str(value))])
{'SS': [string]} set([string])
{'BS': [bytes]} set([bytes])
{'L': list} list
{'M': dict} dict
:returns: The pythonic value of the DynamoDB type.
"""
if not value:
raise TypeError(
'Value must be a nonempty dictionary whose key '
'is a valid dynamodb type.'
)
dynamodb_type = list(value.keys())[0]
try:
deserializer = getattr(
self, f'_deserialize_{dynamodb_type}'.lower()
)
except AttributeError:
raise TypeError(f'Dynamodb type {dynamodb_type} is not supported')
return deserializer(value[dynamodb_type])
def _deserialize_null(self, value):
return None
def _deserialize_bool(self, value):
return value
View on GitHub (pinned to 6e10b029c1)