boto3: Parameter validation failed (ParamValidationError)
TL;DR — botocore.exceptions.ParamValidationError é lançado na sua máquina, antes de qualquer requisição ser enviada — os argumentos que você passou não correspondem à forma esperada da operação. Em código de DynamoDB é quase sempre uma confusão client-vs-resource: o client de baixo nível quer DynamoDB-JSON ({'S': 'abc'}, números como strings), o resource Table quer tipos Python nativos. Combine o estilo com a interface que você está chamando.
O que significa
botocore.exceptions.ParamValidationError: Parameter validation failed:
Invalid type for parameter Item.price.N, value: 42, type: <class 'int'>,
valid types: <class 'str'>O botocore valida toda chamada contra o modelo de API do serviço antes de assiná-la. Uma falha aqui não é um ClientError — o DynamoDB nunca viu a requisição — então except ClientError não a capturará, e nenhum round trip de rede aconteceu. A mensagem nomeia o caminho de parâmetro exato que falhou e o tipo que ele esperava.
Por que acontece
- Valores Python nativos passados ao cliente de baixo nível —
boto3.client('dynamodb')fala DynamoDB JSON cru: todo atributo é um map com tag de tipo e valoresNsão strings ({'N': '42'}, não42). - DynamoDB-JSON passado ao resource
Table— a confusão inversa:boto3.resource('dynamodb').Table(...)espera valores Python simples e faz o marshalling por você. - Objetos de condição onde uma string é esperada — o
KeyConditionExpressiondo paginator de query aceita uma expressão de string; objetosKey('pk').eq(...)falham na validação ali. - Um nome de parâmetro com erro de digitação ou não suportado — chaves desconhecidas falham na validação; um botocore desatualizado também pode rejeitar parâmetros adicionados à API depois de seu modelo empacotado.
Como corrigir
Escolha uma interface e use seu estilo de tipo consistentemente:
# Table resource — native Python types table = boto3.resource('dynamodb').Table('orders') table.put_item(Item={'pk': 'ORDER#1', 'price': Decimal('42')}) # Low-level client — DynamoDB-JSON, numbers as strings client = boto3.client('dynamodb') client.put_item(TableName='orders', Item={'pk': {'S': 'ORDER#1'}, 'price': {'N': '42'}})Use expressões de string com paginators —
KeyConditionExpression='pk = :p'maisExpressionAttributeValues, ou pagine o resourceTablemanualmente comLastEvaluatedKey.Leia o caminho de parâmetro na mensagem —
Item.price.Nte diz exatamente qual atributo e qual tag de tipo falhou; corrija esse campo em vez de adivinhar.Atualize o botocore para falhas de "Unknown parameter" — se o parâmetro é real mas seu modelo de validação o antecede,
pip install -U boto3 botocore.Capture-o separadamente de erros de serviço:
from botocore.exceptions import ClientError, ParamValidationError try: client.put_item(**kwargs) except ParamValidationError as e: # local: fix the call ... except ClientError as e: # remote: DynamoDB rejected it ...
Escrever DynamoDB-JSON à mão é onde essas tags de tipo dão errado — o conversor de DynamoDB JSON traduz entre JSON nativo e o formato de fio com tags de tipo, e o app desktop DynoTable edita itens com o marshalling tratado por você.
Erros relacionados
- Float types are not supported — a outra rejeição de tipo do lado do cliente do boto3 (use
Decimal). - ValidationException: One or more parameter values were invalid — a contraparte do lado do servidor uma vez que a requisição de fato sai.
- Aprenda: DynamoDB JSON & marshalling
Referências
- Error handling — Boto3 documentation
- AttributeValue — Amazon DynamoDB API Reference
- Error handling with DynamoDB — Amazon DynamoDB Developer Guide
Verificado pela última vez em 2026-07-13 contra a documentação oficial da AWS vinculada acima.