DynamoDB ConditionalCheckFailedException
TL;DR — Sua escrita carregava uma ConditionExpression que avaliou como false contra o item atual, então o DynamoDB rejeitou a escrita e deixou o item intocado. Isso normalmente é esperado (concorrência otimista, "criar se não existir") — capture-o e ramifique, não tente novamente às cegas.
O que significa
Ao contrário de um ValidationException, a requisição estava bem formada. O DynamoDB avaliou sua condição e ela não se sustentou, então o PutItem / UpdateItem / DeleteItem (ou um único item dentro de um TransactWriteItems) foi recusado. Nenhum dado mudou. Ele retorna HTTP 400 e não é retentável como está.
Por que isso acontece
- Guard
attribute_not_exists(pk)em uma criação — o item já existe (uma inserção duplicada). - Guard
attribute_exists(pk)em uma atualização/exclusão — o item desapareceu. - Concorrência otimista — uma verificação
version = :expected(ouupdatedAt) onde outro processo de escrita chegou primeiro. - Guards de regra de negócio —
balance >= :amount,#status = :expectedque não correspondem mais ao item armazenado.
Como corrigir
- Trate-o como um resultado normal, não uma falha. Capture a exceção e decida o que uma condição falha significa no seu fluxo (item já existe → retorne-o; versão desatualizada → releia e tente novamente com a nova versão).
- Releia o item atual. Defina
ReturnValuesOnConditionCheckFailure: 'ALL_OLD'para obter o item que causou a falha sem um segundo round-trip — ele volta na própria exceção (o campoItem), e nenhuma capacidade de leitura é consumida. - Releia + recalcule para concorrência, depois tente novamente com a versão fresca — não apenas reenvie o mesmo valor esperado.
Esse laço de reler-e-comparar é exatamente o que a área de preparação do DynoTable faz para edições manuais — ela prepara suas escritas e, em um conflito de bloqueio otimista, mostra o item atual ao lado da sua alteração para você resolver tudo antes de qualquer coisa ser enviada.
Exemplo
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
O que causa um ConditionalCheckFailedException no DynamoDB? Uma escrita (PutItem, UpdateItem, DeleteItem ou um item de TransactWrite) carregou uma ConditionExpression que avaliou como falso contra o item atual — por exemplo attribute_not_exists(pk) em uma chave que já existe, ou uma verificação de versão que não corresponde mais. O DynamoDB rejeita a escrita e deixa o item inalterado.
Como impeço que um ConditionalCheckFailedException derrube meu app? Capture a exceção e trate-a como um resultado esperado, não uma falha. Uma condição falha normalmente significa "alguém chegou primeiro" (concorrência otimista) ou "o item já existe" — ramifique com base nisso em vez de tentar novamente às cegas.
Reproduza
Um PutItem protegido por attribute_not_exists contra uma chave que existe:
await client.send(
new PutItemCommand({
TableName: 'orders',
Item: {pk: {S: 'ORDER#1'}, sk: {S: 'META'}},
ConditionExpression: 'attribute_not_exists(pk)'
})
);Saída real:
ConditionalCheckFailedException: The conditional request failed
HTTP 400A mensagem é deliberadamente pouco informativa — ela nunca diz qual parte da condição falhou, nem o que o item de fato continha. Passe ReturnValuesOnConditionCheckFailure: "ALL_OLD" e o item atual volta em error.Item, o que transforma isso de um palpite em um diff.
Erros relacionados
- TransactionCanceledException — uma condição falha dentro de uma transação.
- ValidationException (overview)
- Exemplo de código: Conditional write in Node.js · in Python (boto3) — padrões executáveis de ConditionExpression.
- Aprenda: Condition expressions · Atomic counters
Referências
- Error handling with DynamoDB — Amazon DynamoDB Developer Guide
- PutItem — Amazon DynamoDB API Reference
- DynamoDB condition expression examples — Amazon DynamoDB Developer Guide
Verificado pela última vez em 2026-07-13 contra a documentação oficial da AWS vinculada acima.
Reproduzido em 2026-07-26 no DynamoDB Local 2.x com o AWS SDK for JavaScript v3.1095.0 — a saída acima é literal.