DynamoDB ConditionalCheckFailedException

TL;DR — Penulisan Anda membawa ConditionExpression yang bernilai false terhadap item saat ini, jadi DynamoDB menolak penulisan itu dan membiarkan item tak tersentuh. Ini biasanya memang wajar (optimistic concurrency, "create if not exists") — tangkap lalu bercabang, jangan mencoba ulang secara membabi buta.

Apa artinya

Berbeda dengan ValidationException, request-nya berbentuk benar. DynamoDB mengevaluasi kondisi Anda dan kondisi itu tidak terpenuhi, jadi PutItem / UpdateItem / DeleteItem (atau satu item di dalam TransactWriteItems) ditolak. Tidak ada data yang berubah. Ia mengembalikan HTTP 400 dan tidak bisa dicoba ulang apa adanya.

Mengapa itu terjadi

  • Penjaga attribute_not_exists(pk) pada create — item sudah ada (sisipan duplikat).
  • Penjaga attribute_exists(pk) pada update/delete — itemnya sudah hilang.
  • Optimistic concurrency — pemeriksaan version = :expected (atau updatedAt) di mana penulis lain sampai lebih dulu.
  • Penjaga aturan bisnisbalance >= :amount, #status = :expected yang tidak lagi cocok dengan item tersimpan.

Bagaimana cara memperbaikinya

  1. Perlakukan sebagai hasil normal, bukan kesalahan. Tangkap exception-nya dan putuskan apa arti kondisi yang gagal dalam alur Anda (item sudah ada → kembalikan; versi usang → baca ulang dan coba lagi dengan versi baru).
  2. Baca kembali item saat ini. Setel ReturnValuesOnConditionCheckFailure: 'ALL_OLD' untuk mendapatkan item yang menyebabkan kegagalan tanpa bolak-balik kedua kalinya — item itu ikut kembali pada exception-nya sendiri (field Item), dan tidak ada read capacity yang dikonsumsi.
  3. Baca ulang + hitung ulang untuk concurrency, lalu coba lagi dengan versi yang segar — jangan cuma mengirim ulang nilai expected yang sama.

Loop baca-ulang-dan-bandingkan itu persis yang dilakukan staging area DynoTable untuk suntingan manual — ia men-stage penulisan Anda dan, saat terjadi konflik optimistic-locking, menampilkan item saat ini bersebelahan dengan perubahan Anda sehingga Anda bisa menyelesaikannya sebelum apa pun terkirim.

Contoh

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

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

try {
  await doc.send(
    new PutCommand({
      TableName: 'Users',
      Item: {pk: 'USER#1', email: 'a@b.com'},
      ConditionExpression: 'attribute_not_exists(pk)' // create-only
    })
  );
} catch (err) {
  if (err instanceof ConditionalCheckFailedException) {
    // Expected: the user already exists. Handle gracefully.
    return {alreadyExists: true};
  }
  throw err;
}

FAQ

Apa yang menyebabkan ConditionalCheckFailedException di DynamoDB? Sebuah penulisan (PutItem, UpdateItem, DeleteItem, atau satu item TransactWrite) membawa ConditionExpression yang bernilai false terhadap item saat ini — misalnya attribute_not_exists(pk) pada key yang sudah ada, atau pemeriksaan versi yang tidak lagi cocok. DynamoDB menolak penulisan itu dan membiarkan item tak berubah.

Bagaimana cara mencegah ConditionalCheckFailedException membuat aplikasi saya crash? Tangkap exception-nya dan perlakukan sebagai hasil yang wajar, bukan kesalahan. Kondisi yang gagal biasanya berarti "orang lain sampai lebih dulu" (optimistic concurrency) atau "itemnya sudah ada" — bercabanglah berdasarkan itu alih-alih mencoba ulang secara membabi buta.

Cara mereproduksinya

Sebuah PutItem yang dijaga attribute_not_exists terhadap key yang memang ada:

await client.send(
  new PutItemCommand({
    TableName: 'orders',
    Item: {pk: {S: 'ORDER#1'}, sk: {S: 'META'}},
    ConditionExpression: 'attribute_not_exists(pk)'
  })
);

Keluaran sebenarnya:

ConditionalCheckFailedException: The conditional request failed
HTTP 400

Pesannya sengaja tidak informatif — ia tidak pernah menyebut bagian kondisi mana yang gagal, atau apa isi item sesungguhnya. Berikan ReturnValuesOnConditionCheckFailure: "ALL_OLD" dan item saat ini akan kembali di error.Item, yang mengubah ini dari menebak-nebak menjadi sebuah diff.

Kesalahan terkait

Referensi

Terakhir diverifikasi 2026-07-13 terhadap dokumentasi resmi AWS yang ditautkan di atas.

Direproduksi 2026-07-26 terhadap DynamoDB Local 2.x dengan AWS SDK for JavaScript v3.1095.0 — keluaran di atas dikutip apa adanya.

Bekerja dengan DynamoDB tanpa Console

Klien desktop DynamoDB yang cepat dan menjalankan SQL sungguhan yang tidak bisa dijalankan DynamoDB — JOINs, GROUP BY, agregasi — dengan editing visual dan agen AI pada kunci Bedrock milik Anda sendiri.

Uji coba gratis 30 hari, tanpa kartu kredit — lalu paket Free tanpa batas waktu.