boto/boto3 · error · TypeError

Value must be a nonempty dictionary whose key is a valid dyn

Error message

Value must be a nonempty dictionary whose key is a valid dynamodb type.

What it means

Raised by TypeDeserializer.deserialize when the input value is falsy (empty dict {}, None, empty string, 0, etc.). The deserializer expects a single-key dict like {'S': 'hello'}; an empty or falsy value has no type key to dispatch on, so the function refuses it immediately with a guard at the top of the method.

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 c7b4afac23)

Solutions

  1. Guard against falsy values before deserializing: if value: TypeDeserializer().deserialize(value).
  2. Treat missing/empty values as None at the application layer.
  3. Ensure the source produces proper single-key DynamoDB type dicts.

Example fix

# before
from boto3.dynamodb.types import TypeDeserializer
td = TypeDeserializer()
for attr, raw in item.items():
    result[attr] = td.deserialize(raw)  # raw may be {}

# after
td = TypeDeserializer()
for attr, raw in item.items():
    result[attr] = td.deserialize(raw) if raw else None
Defensive patterns

Strategy: validation

Validate before calling

from boto3.dynamodb.types import TypeDeserializer

def safe_deserialize(value):
    if not value:
        return None
    return TypeDeserializer().deserialize(value)

Type guard

def is_valid_dynamodb_value(v) -> bool:
    return bool(v) and isinstance(v, dict) and len(v) == 1

Prevention

When it happens

Trigger: TypeDeserializer().deserialize({}) — empty dict. Also deserialize(None), deserialize(''), or deserialize(0). Common when iterating over a response that contains missing/empty attribute values.

Common situations: Iterating DynamoDB Items where some attributes were not returned (None values); passing an empty dict from a malformed API response; deserializing a projection that excluded the attribute.

Related errors


AI-assisted analysis of boto/boto3@c7b4afac23 (2026-08-04). Data as JSON: /data/errors/3614ab5464d8d4ae.json. Report an issue: GitHub.