DynamoDB IdempotentParameterMismatchException
TL;DR — 你以一個在過去 10 分鐘內已被使用的 ClientRequestToken 呼叫 TransactWriteItems,但請求的其餘部分改變了。這個 token 承諾「這是_同一個_交易的重試」— 因此 DynamoDB 拒絕負載不同的 token 重用。只對位元組相同的重試重用 token;為每個新的邏輯交易鑄造新的 token(一個 UUID)。
這是什麼意思
IdempotentParameterMismatchException: DynamoDB rejected the request because
you retried a request with a different payload but with an idempotent token
that was already used.ClientRequestToken 使 TransactWriteItems 具冪等性:多次帶相同 token 的相同呼叫具有單次呼叫的效果,這在逾時掩蓋第一次嘗試是否落地時,保護你免於重複套用一個交易。token 在第一個使用它的請求完成後保持有效 10 分鐘。若在該視窗內有一個請求帶著相同 token 但不同參數抵達,DynamoDB 無法把它當作重試 — 也拒絕把它當作新交易。HTTP 400,原樣不可重試。
為什麼會發生
- 靜態或硬編碼的 token — 每個交易都送出相同的 token 字串,因此第二個(不同的)交易與第一個衝突。
- 從過於粗略的東西衍生的 token — 例如使用者 ID 或表格名稱,因此同一使用者的兩個不同交易共用一個 token。
- 重試以不同方式重建了請求 — 項目內的時間戳、TTL 值或產生的 ID 在第一次嘗試與重試之間改變,因此「相同」的交易不再逐位元組相符。
- 兩條程式碼路徑共用一個 token 來源 — 以相同值播種的平行 worker。
如何修正
為每個邏輯交易產生唯一的 token — 在交易被組合之處產生一個 UUID:
import {randomUUID} from 'node:crypto'; await client.send(new TransactWriteItemsCommand({ ClientRequestToken: token, // created ONCE per logical transaction TransactItems: [...] }));重試時讓 token _隨_請求一起 — 重試同一個已建立的請求物件,而非重建的,這樣負載中的任何東西都無法漂移。(AWS SDK 為它們的自動重試正確地做到這點;bug 幾乎總是重新組合請求的應用層重試。)
在組合前釘住易變的值 — 時間戳與產生的 ID 必須計算一次並在重試時重用,而非重新求值。
不要在 10 分鐘後重用 token 卻期望冪等性 — 超過視窗後,請求被視為全新的,並會再次套用。
DynoTable 桌面應用程式讓你檢視某個交易確切觸及的項目,這讓「我的第一次嘗試真的落地了嗎?」從猜測變成查找。
相關錯誤
- TransactionCanceledException — 交易執行了但被回滾。
- TransactionConflictException — 並行交易觸及了同一項目。
- TransactWriteItems: too many items
- 程式碼範例:TransactWriteItems in Node.js — 展示 ClientRequestToken 的用法。
- 學習:DynamoDB transactions
References
- TransactWriteItems — Amazon DynamoDB API Reference (ClientRequestToken, IdempotentParameterMismatchException)
- Amazon DynamoDB Transactions: How it works — Developer Guide (idempotency)
- Error handling with DynamoDB — Amazon DynamoDB Developer Guide
最後驗證於 2026-07-13,對照上方連結的 AWS 官方文件。