chundev
日期:2026-03-16 環境:Cortex XSOAR 測試環境
在 XSOAR Playbook 中使用 createList + setList 更新 List 時,會遇到 DB Version 'X' and Insert version 'Y' do not match 版本衝突錯誤。根本原因是 XSOAR 的樂觀鎖機制(Optimistic Locking),Playbook 執行過程中快取的版本號已過期。最終解法是寫一個自訂 Automation Script,在 setList 前先 getList 刷新版本號。
開發一個 DRIP 設備清單同步 Playbook,流程為:
在「寫入 List」步驟持續出現:
failed to update list [DRIP_設備清單] in database:
DB Version '7' and Insert version '6' do not match
for id: DRIP_設備清單 on bucket [] [dataListsBucket]
假設: createList 每次重建 List 改變了版本號,導致後續 setList 版本不匹配。
結果: 移除 createList 後,問題依然存在。版本衝突不是 createList 造成的。
做法: createList 設定 continueonerrortype: errorPath,List 已存在時走 error path 繼續。
結果: 同樣的版本衝突錯誤。setList 快取的版本號在 Playbook 長時間執行後已過期。
做法: 在寫入前先刪除舊 List,再用 createList 全新建立。
問題 1: deleteList 不是 XSOAR 內建指令,需要 Core REST API integration。
問題 2: 如果在 Playbook 開頭就刪除,API 全部失敗時 List 會完全不可用。如果移到 Merge 之後才刪除,仍然需要 Core REST API。
結果: 此路不通。
關鍵發現: 版本衝突是因為 Playbook 執行過程中(呼叫 3 次 API + 精簡 + 合併),XSOAR 快取的 List 版本號已經與 DB 不一致。在 Automation Script 內部先 getList 可以刷新版本號到最新,緊接著 setList 就能成功。
# SetListWithRetry automation script 核心邏輯
import time
def main():
list_name = demisto.args().get('listName', '')
list_data = demisto.args().get('listData', '')
max_retries = 5
retry_delay = 2
for attempt in range(max_retries):
# 關鍵:每次重試前先 getList 刷新版本號
demisto.executeCommand('getList', {'listName': list_name})
# 馬上 setList,此時版本號是最新的
result = demisto.executeCommand('setList', {
'listName': list_name,
'listData': list_data
})
if not isError(result[0]):
# 成功
return
error_msg = result[0].get('Contents', '')
if 'do not match' in str(error_msg):
time.sleep(retry_delay)
continue
else:
return_error(f'setList 失敗: {error_msg}')
return
return_error(f'重試 {max_retries} 次後仍失敗')
main()
| 指令 | 用途 | 備註 |
|---|---|---|
createList |
建立新 List | List 已存在會報錯 |
getList |
讀取 List 內容 | 同時刷新版本號快取 |
setList |
覆寫 List 內容 | 有樂觀鎖,版本不匹配會失敗 |
addToList |
新增資料到 List | — |
deleteList |
❌ 不存在 | 需透過 Core REST API |
setList 有樂觀鎖機制 — 不是單純的覆寫,會檢查版本號deleteList 不是內建指令 — 要刪除 List 需要 Core REST API integration(core-api-post uri="/lists/delete")開始
→ API Tracker 1 → 精簡欄位
→ API Tracker 2 → 精簡欄位
→ API Tracker 3 → 精簡欄位
→ 合併 3 份結果
→ SetListWithRetry (getList 刷新 + setList 寫入)
→ 回填資訊 → 結案