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。

如何修正

  1. 為每個邏輯交易產生唯一的 token — 在交易被組合之處產生一個 UUID:

    import {randomUUID} from 'node:crypto';
    
    await client.send(new TransactWriteItemsCommand({
      ClientRequestToken: token, // created ONCE per logical transaction
      TransactItems: [...]
    }));
  2. 重試時讓 token _隨_請求一起 — 重試同一個已建立的請求物件,而非重建的,這樣負載中的任何東西都無法漂移。(AWS SDK 為它們的自動重試正確地做到這點;bug 幾乎總是重新組合請求的應用層重試。)

  3. 在組合前釘住易變的值 — 時間戳與產生的 ID 必須計算一次並在重試時重用,而非重新求值。

  4. 不要在 10 分鐘後重用 token 卻期望冪等性 — 超過視窗後,請求被視為全新的,並會再次套用。

DynoTable 桌面應用程式讓你檢視某個交易確切觸及的項目,這讓「我的第一次嘗試真的落地了嗎?」從猜測變成查找。

相關錯誤

References

最後驗證於 2026-07-13,對照上方連結的 AWS 官方文件。

不必透過主控台就能操作 DynamoDB

DynoTable 是一款快速的 DynamoDB 桌面用戶端 — 瀏覽表格、執行 SQL 風格的查詢,並在本機編輯項目。