Attribute name is a reserved keyword

TL;DR — DynamoDB の予約語の1つ(約 570 個 — statusnamesizetypedatayearcount など多数)である属性名を式で直接使いました。ExpressionAttributeNames のプレースホルダー — status にマッピングした #status — に置き換えると、リクエストが通ります。

意味

ValidationException: 1 validation error detected: Invalid UpdateExpression: Attribute name is a reserved keyword; reserved keyword: status
ValidationException: 1 validation error detected: Invalid KeyConditionExpression: Attribute name is a reserved keyword; reserved keyword: name

DynamoDB は、式(UpdateExpressionConditionExpressionFilterExpressionKeyConditionExpressionProjectionExpression)に リテラルに 現れることができない予約語のリストを保持します。属性がたまたまそれらの1つであるとき、パーサーは式を拒否します。これは ValidationException(HTTP 400)で、名前をエイリアス化するまで リトライ不可 です。メッセージは正確な予約語を示します。

発生する理由

  • 一般的な属性名が予約語と衝突statusnamesizetypedatayearcounttimestampsourceregion、その他数百が予約されています。
  • 予約された属性名を直接リストする ProjectionExpression
  • 予約された名前を参照する FilterExpression/ConditionExpression#status = :s は機能し、status = :s は機能しません)。
  • 数字で始まる、またはスペース、ドット、ハイフンを含む属性名 — これらも ExpressionAttributeNames エイリアスを必要とし、関連する検証エラーを生みます。

修正方法

  1. ExpressionAttributeNames で名前をエイリアス化します。 #placeholder を実際の名前にマッピングし、式でプレースホルダーを使います:
    await doc.send(
      new UpdateCommand({
        TableName: 'Orders',
        Key: {pk: 'ORDER#1'},
        UpdateExpression: 'SET #status = :s',
        ExpressionAttributeNames: {'#status': 'status'},
        ExpressionAttributeValues: {':s': 'shipped'}
      })
    );
  2. プレースホルダーは # の後に英数字/アンダースコアで始まる必要があり、使うすべての #name は定義され(定義したすべては使われ)る必要があります。
  3. 防御的にエイリアス化します — 式内のすべての属性名をエイリアス化すれば、どの語が予約されているかを知る必要が決してなくなります。
  4. リテラルのドットを含む名前を単一のプレースホルダーでエイリアス化します — 文字通り Safety.Warning という名前の属性は、名前全体に1つのエイリアス({'#sw': 'Safety.Warning'})が必要です。エイリアス化されていない . はドキュメントパスの区切りとして読まれるからです。本当にネストされたパスには、代わりに各セグメントをエイリアス化します(#pr.#5star)。

よくある質問

DynamoDB で "Attribute name is a reserved keyword" を修正するには? ExpressionAttributeNames で属性をエイリアス化します。#status のようなプレースホルダーを実際の名前 "status" にマッピングし、リテラルの語の代わりに式で #status を使います。プレースホルダーは # で始まる必要があり、定義したすべてが使われる必要があります。

どの DynamoDB 属性名が予約されていますか? 約 570 個の予約語があり、status、name、size、type、data、year、count、timestamp、region のような日常的な名前を含みます。リストを暗記するのではなく、ExpressionAttributeNames で式内のすべての属性名をエイリアス化してください。

関連するエラー

参考資料

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

Console なしで DynamoDB を扱う

DynamoDB では実行できない本物の SQL(JOINs、GROUP BY、集計)を実行する高速な DynamoDB デスクトップクライアント。ビジュアル編集と、あなた自身の Bedrock キーで動く AI エージェントを備えています。

30日間無料トライアル、クレジットカード不要 — その後は期限のない Free プラン。