ValidationException: Query condition missed key schema element

TL;DR — KeyConditionExpression には、パーティションキーに対する等価条件(=)が必ず必要です。キー以外の属性で検索したいなら、その属性をキーに持つ GSI/LSI に対する Query が必要です — または FilterExpression 付きの Scan を使います。

意味

完全なメッセージはたいてい次のようになります。

ValidationException: Query condition missed key schema element: pk

コロンの後ろの名前は、あなたのテーブルのパーティションキー属性なので、テーブルごとに変わります。

Queryキー に対してしか動きません。DynamoDB は、KeyConditionExpression がパーティションキーをまったく含んでいないか、テーブル(または対象のインデックス)のパーティション/ソートキーではない属性を指定している、と告げています。

発生する理由

  • KeyConditionExpression が、パーティションキーではなく 通常の属性(例: emailstatus)で絞り込んでいる。
  • ベーステーブル に対してクエリしているのに、その属性は GSI 上でしかキーになっていない — IndexName を忘れている。
  • パーティションキーはあるが = 以外の演算子を使っている(パーティションキーは完全一致でなければならず、<>begins_withbetween をサポートするのは ソート キーだけです)。
  • 属性名のタイプミスで、スキーマと一致しなくなっている。

修正方法

  1. パーティションキーに = を使ってクエリします。 すべての Query には pk = :pk(テーブルの実際のキー名を使う)が必要です。
  2. キー以外の属性でクエリしたいですか? その属性をパーティションキーに持つ GSI を作成し、IndexName を渡します。
  3. たまにしかアクセスしませんか? Query の代わりに FilterExpression 付きの Scan を使います — ただし Scan はテーブル全体を読むことに注意してください。

import {DynamoDBClient} from '@aws-sdk/client-dynamodb';
import {DynamoDBDocumentClient, QueryCommand} from '@aws-sdk/lib-dynamodb';

const doc = DynamoDBDocumentClient.from(new DynamoDBClient({}));

// Query the base table by its partition key:
await doc.send(
  new QueryCommand({
    TableName: 'Orders',
    KeyConditionExpression: 'pk = :pk',
    ExpressionAttributeValues: {':pk': 'USER#123'}
  })
);

// Query by a non-key attribute → use a GSI that keys on it
// ("status" is a DynamoDB reserved word, so alias it with #status):
await doc.send(
  new QueryCommand({
    TableName: 'Orders',
    IndexName: 'byStatus',
    KeyConditionExpression: '#status = :s',
    ExpressionAttributeNames: {'#status': 'status'},
    ExpressionAttributeValues: {':s': 'SHIPPED'}
  })
);

よくある質問

「Query condition missed key schema element」はどういう意味ですか? KeyConditionExpression がパーティションキーをまったく含んでいないか、対象のテーブルまたはインデックスのパーティションキー/ソートキーではない属性を指定しています。すべての Query には、パーティションキーに対する等価条件が必要です。

キー以外の属性で DynamoDB をクエリするには? その属性をパーティションキーに持つ GSI を作成し、Query で IndexName を渡します — あるいは、たまにしかアクセスしないなら FilterExpression 付きの Scan を使います。ただし Scan はテーブル全体を読むことを念頭に置いてください。

再現方法

条件にソートキーしか指定していない Query です。

await client.send(
  new QueryCommand({
    TableName: 'orders',
    KeyConditionExpression: 'sk = :s',
    ExpressionAttributeValues: {':s': {S: 'META'}}
  })
);

実際の出力:

ValidationException: Query condition missed key schema element
HTTP 400

すべての Query は、ちょうど1つのパーティションキーを固定しなければなりません。ソートキーだけで検索したいという要望は、そのアクセスパターンに Query ではなく GSI が必要だという典型的なサインです — あるいは、本当にすべてのパーティションを読む必要があるなら Scan です。

関連するエラー

参考資料

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

2026-07-26 に DynamoDB Local 2.x と AWS SDK for JavaScript v3.1095.0 で再現しました — 上記の出力はそのままの逐語です。

Console なしで DynamoDB を扱う

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

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