DynamoDB UpdateItem with the AWS CLI

Five arguments, three of them DynamoDB JSON, all of them fighting your shell: that is what makes aws dynamodb update-item fiddly, not the update itself. What the CLI adds on top of every other client is a second place the request can be rejected, and a set of exit codes precise enough to tell you which one it was.

Code

aws dynamodb update-item \
  --table-name 'Music' \
  --key '{"Artist":{"S":"Arturo Sandoval"},"SongTitle":{"S":"Cubano Chant"}}' \
  --update-expression 'SET #upd0 = :updValue0, #upd1 = :updValue1 ADD #upd2 :updValue2' \
  --expression-attribute-names '{"#upd0":"Genre","#upd1":"Year","#upd2":"Awards"}' \
  --expression-attribute-values '{":updValue0":{"S":"Latin Jazz"},":updValue1":{"N":"1994"},":updValue2":{"N":"1"}}' \
  --return-values ALL_NEW

Run against an item that had neither Genre nor Awards, that command prints:

{
    "Attributes": {
        "Artist": {
            "S": "Arturo Sandoval"
        },
        "Awards": {
            "N": "1"
        },
        "Genre": {
            "S": "Latin Jazz"
        },
        "Year": {
            "N": "1994"
        },
        "SongTitle": {
            "S": "Cubano Chant"
        }
    }
}

ADD on an absent Awards started it at zero, and the attributes came back in the service's order rather than the order the expression wrote them. Do not pipe this into anything positional.

Explanation

  • --key — the full primary key, in DynamoDB JSON. Pass only the partition key of a composite-key table and you get ValidationException: The number of conditions on the keys is invalid, not a partial match.

  • --update-expressionSET, ADD, REMOVE and DELETE clauses, aliased through --expression-attribute-names. ADD #upd2 :updValue2 here is an atomic increment on Awards; the full clause grammar is in update expressions.

  • Numbers are quoted strings, and the CLI checks that before DynamoDB does. Write {"N":1994} instead of {"N":"1994"} and nothing leaves your machine:

    aws: [ERROR]: An error occurred (ParamValidation): Parameter validation failed:
    Invalid type for parameter ExpressionAttributeValues.:y.N, value: 1994, type: <class 'int'>, valid types: <class 'str'>
  • The exit code tells you which half failed. That client-side rejection exits 252. A request DynamoDB actually answered and refused exits 254:

    aws: [ERROR]: An error occurred (ValidationException) when calling the UpdateItem operation: Invalid UpdateExpression: Attribute name is a reserved keyword; reserved keyword: Year

    A 252 is always a bug in your JSON. A 254 may be a condition you deliberately expected to fail, so scripts should branch on the two rather than on non-zero.

  • Without --return-values the command prints nothing at all and exits 0. There is no "1 item updated" line to grep, so silence is success. UPDATED_NEW returns only the attributes the expression touched, which is the cheap option when you only need the new counter value.

  • Quote once, then use a file. Single-quote each JSON argument so the shell leaves " and $ alone, and move anything long into --expression-attribute-values file://values.json rather than escaping it twice.

  • Upsert semanticsupdate-item creates the item when the key is absent, which is how Awards appeared above. Add --condition-expression "attribute_exists(Artist)" to make it update-only.

Nothing here builds the expression for you

Of the five clients documented on this site, exactly one will generate an UpdateExpression: the Go SDK's expression package. Node, Python and Java all hand you the string to write. The CLI is the worst case of the four, because you are also hand-writing both alias maps and the DynamoDB JSON, inside a shell that wants to interpret the same characters.

The DynamoDB Expression Builder closes that gap: assemble the clauses in the browser, copy a ready-quoted aws dynamodb update-item command. To make the same edit against a real table without escaping a single quote, download DynoTable.

References

Last verified 2026-07-28 against the official AWS documentation linked above.

Work with DynamoDB without the Console

A fast DynamoDB desktop client that runs the real SQL DynamoDB can’t — JOINs, GROUP BY, aggregates — with visual editing and an AI agent on your own Bedrock keys.

Free 30-day trial, no credit card — then the Free plan with no time limit.