AWS CLI での DynamoDB PutItem
aws dynamodb put-item はアイテム全体を書き込み、同じプライマリキーを持つ既存のアイテムを置き換えます(update-item との違いはアイテムベースのアクションが扱います)。この問題に対する CLI 自身の上乗せ分はシェルです。--item はクォートされた 1 個の引数として DynamoDB JSON を受け取り、属性値はすべて型付きです。
コード
aws dynamodb put-item \
--table-name 'Music' \
--item '{"Artist":{"S":"Arturo Sandoval"},"SongTitle":{"S":"Cubano Chant"},"AlbumTitle":{"S":"Danzon"},"Year":{"N":"1994"},"Awards":{"N":"0"}}' \
--condition-expression 'attribute_not_exists(#cond0) AND attribute_not_exists(#cond1)' \
--expression-attribute-names '{"#cond0":"Artist","#cond1":"SongTitle"}'成功すると、コマンドは何も出力せず終了コード 0 で終わります。アイテムがすでに存在する場合、条件が失敗します。
An error occurred (ConditionalCheckFailedException) when calling the PutItem operation:
The conditional request failed解説
無音と終了コード 0 だけが成功の合図です。put-item は --return-values を求めない限り JSON を出力しないので、確認のために標準出力を grep するスクリプトは決して発火しません。$? を見てください。上のコマンドを aws-cli/2.36.9 で 2 回実行した結果です。
first run: (no output) exit 0
second run: aws: [ERROR]: An error occurred (ConditionalCheckFailedException) when calling the PutItem operation: The conditional request failed
exit 254254 は「サービスが拒否した」であって「CLI が壊れた」ではありません。AWS CLI は自身の構文や設定の問題に 252/253 を、それ以外すべてに 255 を予約しているので、ConditionalCheckFailedException も ValidationException もスロットリングも、そろって同じ 254 に着地します。想定内の条件失敗と本物の障害をスクリプトで区別する必要があるなら、終了コードではなくエラー名をパースしてください。また 2.36.9 はメッセージの先頭に aws: [ERROR]: を付けます。以前のビルドにはなかったので、^An error occurred にアンカーした正規表現は、CLI を上げた途端に黙ってマッチしなくなります。
条件付き書き込みは失敗してもコストがかかります。条件はサービスがアイテムを見つけた後に評価され、AWS は「if the expression evaluates to false, DynamoDB still consumes write capacity units from the table」と明言しています(2026-07-28 取得)。作成専用の put をリトライループで囲むと、試行のたびに課金されます。規模感として、約 15 KB のアイテムを put して成功したときに --return-consumed-capacity TOTAL が報告したのは "CapacityUnits": 15 でした。書き込みは、読み取りの 4 KB ではなく 1 KB 単位で切り上げられます。
--return-values-on-condition-check-failure は機能しますが、CLI がその答えを隠します。これは、2 回目の読み取りなしに どの アイテムが書き込みをブロックしたかを教えてくれるフラグです。付けると 2.36.9 はこう出力します。
aws: [ERROR]: An error occurred (ConditionalCheckFailedException) when calling the PutItem operation: The conditional request failed
Additional error details:
Item: <complex value>
Use "--cli-error-format json" or another error format to see the full details.アイテムはずっとレスポンスの中にあります。既定のエラーフォーマッタがそれを描画するのを拒んでいるだけです。取り出すには --cli-error-format json を付けてください(--return-values ALL_OLD は無条件版のいとこで、成功時にしか発火しません。5 つの選択肢は ReturnValues が扱います)。
クォーティングがもう半分の仕事です。--item 引数は、クォートされた数値(1994 ではなく必ず {"N": "1994"})を含む JSON を含む、1 個のシェルトークンです。アポストロフィを含むもの、そして数百バイトを超えるアイテムは、--item file://song.json の方が楽です。--cli-input-json file://request.json はさらに進んで、条件式も含めたリクエスト全体を受け取ります。これはレビューで差分を取れる形式でもあります。
エイリアスは省いてよい飾りではありません。#cond0/#cond1 は --expression-attribute-names を通じて Artist/SongTitle に解決されます。名前をそのまま書いてもうまくいきますが、それはどれかが予約語と衝突するまでの話で、その時点で、自分では変えていない名前が原因でコマンドが失敗します。
ビジュアルに行う
--item 用の型付き JSON を手で打つことが、この手のコマンドがいちばん死ぬところです。無料の DynamoDB JSON コンバータは、普通の JSON からこのフラグが求める {"S": …} / {"N": …} 形式を返してくれるので、そのまま file:// のペイロードとして保存できます。
自分のテーブルに対してアイテムを追加・編集するには — 属性ごとの入力フォーム、型のピッカー、結果を CLI コマンドとしてコピーし直す機能 — DynoTable をダウンロードしてください。
関連ガイド
- DynamoDB の条件式 —
attribute_not_exists、楽観的ロックなど。 - DynamoDB のデータ型 — 各属性型を DynamoDB JSON でどう書くか。
- DynamoDB ConditionalCheckFailedException — アイテムがすでに存在するときに作成専用の条件が投げるもの。
- DynamoDB ValidationException — 不正なアイテムや式に対する何でも受けのエラー。
参考資料
- PutItem — Amazon DynamoDB API Reference
- put-item — AWS CLI Command Reference
- Understanding return codes — AWS CLI User Guide
- Condition expressions — Amazon DynamoDB Developer Guide
- Working with items and attributes — Amazon DynamoDB Developer Guide
2026-07-28 に、ポート 9000 の DynamoDB Local(amazon/dynamodb-local)に対し aws-cli/2.36.9 で再現しました。終了コード、エラーテキスト、キャパシティの読み取り値はそのままの出力です。書き込み失敗時のキャパシティに関する主張は、実測ではなく AWS ドキュメントからの引用です。DynamoDB Local は条件失敗の経路で ConsumedCapacity を返さないためです。