boto3 : Parameter validation failed (ParamValidationError)

En bref — botocore.exceptions.ParamValidationError est levée sur ta machine, avant l'envoi de toute requête — les arguments que tu as passés ne correspondent pas à la forme attendue de l'opération. Dans du code DynamoDB, c'est presque toujours une confusion client-vs-resource : le client de bas niveau veut du DynamoDB-JSON ({'S': 'abc'}, nombres sous forme de chaînes), la resource Table veut des types Python natifs. Adapte le style à l'interface que tu appelles.

Ce que ça signifie

botocore.exceptions.ParamValidationError: Parameter validation failed:
Invalid type for parameter Item.price.N, value: 42, type: <class 'int'>,
valid types: <class 'str'>

# what the engine actually returns, reproduced against boto3 1.43.67 on Python 3.11.15:
ParamValidationError: Parameter validation failed:
Invalid type for parameter Item.price.N, value: 42, type: <class 'int'>, valid types: <class 'str'>

botocore valide chaque appel par rapport au modèle d'API du service avant de le signer. Un échec ici n'est pas une ClientError — DynamoDB n'a jamais vu la requête — donc except ClientError ne l'attrapera pas, et aucun aller-retour réseau n'a eu lieu. Le message nomme le chemin exact du paramètre qui a échoué et le type qu'il attendait.

Pourquoi ça arrive

  • Des valeurs Python natives passées au client de bas niveauboto3.client('dynamodb') parle le DynamoDB JSON brut : chaque attribut est une map typée et les valeurs N sont des chaînes ({'N': '42'}, pas 42).
  • Du DynamoDB-JSON passé à la resource Table — la confusion inverse : boto3.resource('dynamodb').Table(...) attend des valeurs Python simples et fait le marshalling pour toi.
  • Des objets Condition là où une chaîne est attendue — le KeyConditionExpression du paginateur de Query accepte une expression sous forme de chaîne ; les objets Key('pk').eq(...) échouent à la validation à cet endroit.
  • Un nom de paramètre erroné ou non pris en charge — les clés inconnues échouent à la validation ; un botocore obsolète peut aussi rejeter des paramètres ajoutés à l'API après son modèle embarqué.

Comment le corriger

  1. Choisis une interface et utilise son style de types de façon cohérente :

    # 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'}})
  2. Utilise des expressions sous forme de chaînes avec les paginateursKeyConditionExpression='pk = :p' plus ExpressionAttributeValues, ou paginate la resource Table manuellement avec LastEvaluatedKey.

  3. Lis le chemin du paramètre dans le messageItem.price.N t'indique exactement quel attribut et quelle balise de type ont échoué ; corrige ce champ précis plutôt que de deviner.

  4. Mets à jour botocore pour les échecs « Unknown parameter » — si le paramètre est réel mais que ton modèle de validation le précède, pip install -U boto3 botocore.

  5. Attrape-la séparément des erreurs de service :

    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
        ...

Écrire du DynamoDB-JSON à la main est là où ces balises de type tournent mal — le convertisseur DynamoDB JSON traduit entre le JSON natif et le format filaire typé, et l'application de bureau DynoTable édite les éléments avec le marshalling géré pour toi.

Reproduire l'erreur

Passe une chaîne là où boto3 attend le mapping Key. La vérification est entièrement côté client :

import boto3
boto3.client('dynamodb', region_name='us-east-1').get_item(TableName='repro', Key='not-a-dict')

Sortie réelle :

ParamValidationError: Parameter validation failed:
Invalid type for parameter Key, value: not-a-dict, type: <class 'str'>, valid types: <class 'dict'>

botocore nomme le paramètre, la valeur reçue, son type et le type attendu — quatre faits en un seul message. Rien n'a été envoyé à AWS : aucune capacité consommée et rien à réessayer ; le correctif est toujours au site d'appel.

Erreurs liées

Références

Dernière vérification le 2026-07-13 par rapport à la documentation officielle AWS liée ci-dessus.

Reproduit le 2026-07-26 avec boto3 1.43.56 / botocore 1.43.56 — la sortie ci-dessus est reproduite telle quelle.

Travaille avec DynamoDB sans la Console

Un client de bureau rapide pour DynamoDB qui exécute le vrai SQL que DynamoDB ne peut pas — JOINs, GROUP BY, agrégations — avec édition visuelle et un agent IA sur tes propres clés Bedrock.

Essai gratuit de 30 jours, sans carte bancaire — ensuite la formule Gratuit, sans limite de durée.