boto3: Parameter validation failed (ParamValidationError)

TL;DR — botocore.exceptions.ParamValidationError は、リクエストが送られる前に、あなたのマシン上で 発生します。渡した引数が操作の期待する形状と一致しないのです。DynamoDB コードでは、ほぼ必ず client vs resource の取り違えです: 低レベルの client は DynamoDB-JSON({'S': 'abc'}、数値は文字列)を求め、Table リソースはネイティブの Python 型を求めます。スタイルを呼び出しているインターフェースに合わせてください。

意味

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

botocore は、署名する前にすべての呼び出しをサービスの API モデルに対して検証します。ここでの失敗は ClientError ではありません。DynamoDB はリクエストを見ていないため、except ClientError は捕捉せず、ネットワークのラウンドトリップは発生していません。メッセージは、失敗した正確なパラメータパスと期待した型を示します。

発生する理由

  • 低レベルクライアントに渡されたネイティブの Python 値boto3.client('dynamodb') は生の DynamoDB JSON を話します: すべての属性は型タグ付きのマップで、N 値は 文字列42 ではなく {'N': '42'})です。
  • Table リソースに渡された DynamoDB-JSON — 逆の取り違え: boto3.resource('dynamodb').Table(...) はプレーンな Python 値を期待し、マーシャリングを代わりに行います。
  • 文字列が期待される場所での Condition オブジェクト — クエリのページネーターの KeyConditionExpression は文字列式を受け付けます。Key('pk').eq(...) オブジェクトはそこで検証に失敗します。
  • タイプミスまたはサポートされないパラメータ名 — 不明なキーは検証に失敗します。古い botocore は、そのバンドルされたモデルの後に API に追加されたパラメータも拒否できます。

修正方法

  1. 1つのインターフェースを選び、その型スタイルを一貫して使います:

    # 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. ページネーターには文字列式を使いますKeyConditionExpression='pk = :p'ExpressionAttributeValues を加える、または LastEvaluatedKeyTable リソースを手動でページングします。

  3. メッセージのパラメータパスを読みますItem.price.N は、どの属性とどの型タグが失敗したかを正確に教えます。推測ではなくそのフィールドを修正します。

  4. 「Unknown parameter」の失敗には botocore をアップグレードします — パラメータが本物なのに検証モデルがそれより古い場合は pip install -U boto3 botocore

  5. サービスエラーとは別に捕捉します:

    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 を手書きするところで、これらの型タグが誤ります。DynamoDB JSON コンバーター はネイティブ JSON と型タグ付きのワイヤーフォーマットの間を変換し、DynoTable デスクトップアプリ はマーシャリングを代わりに処理してアイテムを編集します。

関連するエラー

References

最終検証日 2026-07-13、上記にリンクした公式 AWS ドキュメントに照らして確認しました。

Console なしで DynamoDB を扱う

DynoTable は DynamoDB 向けの高速なデスクトップクライアントです — テーブルを閲覧し、SQL スタイルのクエリを実行し、アイテムをローカルで編集できます。