boto3: Parameter validation failed (ParamValidationError)
TL;DR — botocore.exceptions.ParamValidationError wird auf deiner Maschine ausgelöst, bevor irgendeine Anfrage gesendet wird — die von dir übergebenen Argumente passen nicht zur erwarteten Form der Operation. In DynamoDB-Code ist es fast immer eine Client-vs-Resource-Verwechslung: der Low-Level-client will DynamoDB-JSON ({'S': 'abc'}, Zahlen als Zeichenketten), die Table-Resource will native Python-Typen. Passe den Stil an die Schnittstelle an, die du aufrufst.
Was es bedeutet
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 validiert jeden Aufruf gegen das API-Modell des Dienstes, bevor es ihn signiert. Ein Fehler hier ist kein ClientError — DynamoDB hat die Anfrage nie gesehen —, also fängt except ClientError ihn nicht ab, und es fand kein Netzwerk-Roundtrip statt. Die Meldung benennt den genauen Parameterpfad, der fehlgeschlagen ist, und den Typ, den er erwartet hat.
Warum es passiert
- Native Python-Werte an den Low-Level-Client übergeben —
boto3.client('dynamodb')spricht rohes DynamoDB-JSON: jedes Attribut ist eine typmarkierte Map undN-Werte sind Zeichenketten ({'N': '42'}, nicht42). - DynamoDB-JSON an die
Table-Resource übergeben — die umgekehrte Verwechslung:boto3.resource('dynamodb').Table(...)erwartet einfache Python-Werte und übernimmt das Marshalling für dich. - Condition-Objekte, wo eine Zeichenkette erwartet wird — der
KeyConditionExpressiondes Query-Paginators akzeptiert einen String-Ausdruck;Key('pk').eq(...)-Objekte scheitern dort an der Validierung. - Ein vertippter oder nicht unterstützter Parametername — unbekannte Schlüssel scheitern an der Validierung; ein veraltetes botocore kann außerdem Parameter ablehnen, die der API nach seinem gebündelten Modell hinzugefügt wurden.
So behebst du es
Wähle eine Schnittstelle und nutze ihren Typstil konsistent:
# 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'}})Nutze String-Ausdrücke mit Paginatoren —
KeyConditionExpression='pk = :p'plusExpressionAttributeValues, oder paginiere dieTable-Resource manuell mitLastEvaluatedKey.Lies den Parameterpfad in der Meldung —
Item.price.Nsagt dir genau, welches Attribut und welches Typ-Tag fehlgeschlagen ist; behebe genau dieses eine Feld, statt zu raten.Aktualisiere botocore bei "Unknown parameter"-Fehlern — wenn der Parameter echt ist, dein Validierungsmodell ihm aber vorausgeht,
pip install -U boto3 botocore.Fange ihn getrennt von Service-Fehlern ab:
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 ...
DynamoDB-JSON von Hand zu schreiben ist der Ort, an dem diese Typ-Tags schiefgehen — der DynamoDB-JSON-Konverter übersetzt zwischen nativem JSON und dem typmarkierten Wire-Format, und die DynoTable-Desktop-App bearbeitet Items mit erledigtem Marshalling für dich.
So reproduzierst du es
Übergib einen String, wo boto3 das Key-Mapping erwartet. Die Prüfung passiert vollständig clientseitig:
import boto3
boto3.client('dynamodb', region_name='us-east-1').get_item(TableName='repro', Key='not-a-dict')Echte Ausgabe:
ParamValidationError: Parameter validation failed:
Invalid type for parameter Key, value: not-a-dict, type: <class 'str'>, valid types: <class 'dict'>botocore benennt den Parameter, den erhaltenen Wert, dessen Typ und den gewünschten Typ — vier Fakten in einer Meldung. Es wurde nichts an AWS gesendet, also wurde keine Kapazität verbraucht und es gibt nichts zu wiederholen; die Lösung liegt immer an der Aufrufstelle.
Verwandte Fehler
- Float types are not supported — boto3s andere clientseitige Typablehnung (nutze
Decimal). - ValidationException: One or more parameter values were invalid — das serverseitige Gegenstück, sobald die Anfrage tatsächlich rausgeht.
- Learn: DynamoDB-JSON & Marshalling
Referenzen
- Error handling — Boto3 documentation
- AttributeValue — Amazon DynamoDB API Reference
- Error handling with DynamoDB — Amazon DynamoDB Developer Guide
Zuletzt verifiziert am 2026-07-13 gegen die oben verlinkte offizielle AWS-Dokumentation.
Am 2026-07-26 gegen boto3 1.43.56 / botocore 1.43.56 reproduziert — die Ausgabe oben ist wortgetreu.