DynamoDB TransactWriteItems with the AWS CLI
The whole transaction goes to aws dynamodb transact-write-items as one --transact-items JSON array, so the CLI's edges are the interesting part: where quoting breaks, what the exit code means, and the fact that the default error output drops the field you need to debug a cancellation. What a transaction buys you is the same in every SDK.
Code
aws dynamodb transact-write-items \
--transact-items '[
{
"Update": {
"TableName": "Music",
"Key": {"Artist": {"S": "Arturo Sandoval"}, "SongTitle": {"S": "Cubano Chant"}},
"UpdateExpression": "SET #upd0 = #upd0 - :one",
"ConditionExpression": "#upd0 >= :one",
"ExpressionAttributeNames": {"#upd0": "Awards"},
"ExpressionAttributeValues": {":one": {"N": "1"}}
}
},
{
"Update": {
"TableName": "Music",
"Key": {"Artist": {"S": "Arturo Sandoval"}, "SongTitle": {"S": "A Mis Abuelos"}},
"UpdateExpression": "SET #upd0 = if_not_exists(#upd0, :zero) + :one",
"ExpressionAttributeNames": {"#upd0": "Awards"},
"ExpressionAttributeValues": {":one": {"N": "1"}, ":zero": {"N": "0"}}
}
}
]'A committed transaction prints nothing and exits 0. There is no response body to check, so in a script the exit code is the result.
Explanation
--transact-items— up to 100Put/Update/Delete/ConditionCheckactions, 4 MB aggregate, values in DynamoDB JSON. Actions can span tables in the same account and Region, and no two of them may target the same item.Three exit codes, three different failures.
0committed.252means the CLI's own parameter validation rejected the request and nothing was sent.254means DynamoDB answered and said no. That distinction is worth branching on: a 252 is a bug in your JSON, a 254 may be a condition you expected to fail.Default error format — drops the per-action reasons. aws-cli v2 prints the summary and then tells you it is withholding the detail:
aws: [ERROR]: An error occurred (TransactionCanceledException) when calling the TransactWriteItems operation: Transaction cancelled, please refer cancellation reasons for specific reasons [ConditionalCheckFailed, None] Additional error details: CancellationReasons: <complex value> Use "--cli-error-format json" or another error format to see the full details.Re-run the same command with
--cli-error-format jsonand the structure arrives intact, one entry per action, in--transact-itemsorder:{ "Message": "Transaction cancelled, please refer cancellation reasons for specific reasons [ConditionalCheckFailed, None]", "Code": "TransactionCanceledException", "CancellationReasons": [ { "Code": "ConditionalCheckFailed", "Message": "The conditional request failed" }, { "Code": "None" } ] }Here the first update's
Awards >= 1condition failed;Nonemarks the second action as innocent, and note it carries noMessagefield at all. Every other code is decoded on the TransactionCanceledException page.Targeting one item twice is not a cancellation. It fails validation before anything is attempted, which is why there are no reasons to print:
aws: [ERROR]: An error occurred (ValidationException) when calling the TransactWriteItems operation: Transaction request cannot include multiple operations on one itemConditionCheck— asserts a condition on an item the transaction does not modify, and vetoes the whole transaction if it fails.--client-request-token— a fixed token makes re-runs idempotent for 10 minutes. Reuse the same token with any parameter changed and DynamoDB returnsIdempotentParameterMismatchrather than silently applying the new payload.The array in a file —
--transact-items file://transaction.jsonsidesteps shell quoting entirely, and the file is diffable.
The 2× is measurable from the shell
Run the same single-item update twice, once inside a transaction and once outside, both with --return-consumed-capacity TOTAL. DynamoDB Local reports 2.0 capacity units for the transactional write and 1.0 for the plain one: the prepare and the commit each bill.
That is the whole argument against reaching for a transaction by default. For atomicity on one item you already have a cheaper tool in a conditional write, which bills once. To price a workload that does this millions of times, the DynamoDB pricing calculator takes the doubled write count directly. If assembling DynamoDB JSON in a shell is the part you want to stop doing, DynoTable edits items against a real table and shows you the expression it generated.
Related examples
- DynamoDB TransactWriteItems in Node.js — the same transaction with AWS SDK v3.
- DynamoDB TransactWriteItems in Python — the same transaction with boto3.
- DynamoDB BatchWriteItem with the AWS CLI — bulk writes when you don't need atomicity.
- DynamoDB transactions — isolation, idempotency, and when transactions are worth it.
- DynamoDB TransactionCanceledException — every cancellation-reason code, decoded.
- "Too many actions in a TransactWriteItems call" — the 100-action and 4 MB transaction limits.
- "Transaction request cannot include multiple operations on one item" — one action per item, per transaction.
References
- TransactWriteItems — Amazon DynamoDB API Reference
- transact-write-items — AWS CLI Command Reference
- Amazon DynamoDB transactions: how it works — Amazon DynamoDB Developer Guide
- DynamoDB read and write operations (capacity unit consumption) — Amazon DynamoDB Developer Guide
Last verified 2026-07-28 against the official AWS documentation linked above.