From ddda084ff901b5811022827c73bdb9556125ad95 Mon Sep 17 00:00:00 2001 From: Lecky Lao Date: Sat, 28 Mar 2026 22:06:19 +1100 Subject: [PATCH] fix(openclaw-plugin): prevent CONFLICT errors with commit lock When auto-capture in afterTurn and memory_store tool both try to commit to the same OpenViking session simultaneously, the server returns a CONFLICT error. This adds a simple in-memory lock mechanism: - Add commitLocks Set to track in-flight commits per session - Skip afterTurn if a commit is already in progress for that session - Release lock in finally block to ensure cleanup on error This prevents the error: 'OpenViking request failed [CONFLICT]: Session xxx already has a commit in progress' --- examples/openclaw-plugin/context-engine.ts | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/examples/openclaw-plugin/context-engine.ts b/examples/openclaw-plugin/context-engine.ts index a81390945..47acf25c5 100644 --- a/examples/openclaw-plugin/context-engine.ts +++ b/examples/openclaw-plugin/context-engine.ts @@ -10,6 +10,9 @@ import { } from "./memory-ranking.js"; import { sanitizeToolUseResultPairing } from "./session-transcript-repair.js"; + +// Simple in-memory lock to prevent concurrent commits +const commitLocks = new Set(); type AgentMessage = { role?: string; content?: unknown; @@ -572,6 +575,17 @@ export function createMemoryOpenVikingContextEngine(params: { } const OVSessionId = afterTurnParams.sessionId; + + // Skip if a commit is already in progress for this session + if (commitLocks.has(OVSessionId)) { + logger.info(`openviking: afterTurn skipped (commit in progress for ${OVSessionId})`); + diag("afterTurn_skip", OVSessionId, { + reason: "commit_lock_contention", + }); + return; + } + commitLocks.add(OVSessionId); + try { const agentId = resolveAgentId(OVSessionId); @@ -673,6 +687,8 @@ export function createMemoryOpenVikingContextEngine(params: { diag("afterTurn_error", OVSessionId, { error: String(err), }); + } finally { + commitLocks.delete(OVSessionId); } },