From d3e234c2d4e28caa07ff0bca0ad4b617ba6f5c7b Mon Sep 17 00:00:00 2001 From: iliya Date: Thu, 26 Feb 2026 22:12:53 +0200 Subject: [PATCH] fix: add retry logic to sendInboxMessage for concurrent writes On Windows, parallel writes to the same inbox file cause race conditions where atomicWrite verification fails (another process overwrites between write and verify). Added retry loop (8 attempts) matching the existing pattern in addTaskComment. Bumps teamctl version to 11. Fixes CI failure: test (windows-latest) "parallel messages to same inbox" --- .../services/team/TeamAgentToolsInstaller.ts | 28 +++++++++++++------ 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/src/main/services/team/TeamAgentToolsInstaller.ts b/src/main/services/team/TeamAgentToolsInstaller.ts index eb0a0f01..60b3b767 100644 --- a/src/main/services/team/TeamAgentToolsInstaller.ts +++ b/src/main/services/team/TeamAgentToolsInstaller.ts @@ -6,7 +6,7 @@ import * as path from 'path'; import { atomicWriteAsync } from './atomicWrite'; const TOOL_FILE_NAME = 'teamctl.js'; -const TOOL_VERSION = 10; +const TOOL_VERSION = 11; function buildTeamCtlScript(): string { const script = String.raw`#!/usr/bin/env node @@ -420,15 +420,25 @@ function sendInboxMessage(paths, teamName, flags) { messageId, }; - const existing = readJson(inboxPath, []); - const list = Array.isArray(existing) ? existing : []; - list.push(payload); - atomicWrite(inboxPath, JSON.stringify(list, null, 2)); - const verify = readJson(inboxPath, []); - if (!Array.isArray(verify) || !verify.some((m) => m && m.messageId === messageId)) { - die('Inbox write verification failed'); + var lastErr; + for (var attempt = 0; attempt < 8; attempt++) { + try { + var existing = readJson(inboxPath, []); + var list = Array.isArray(existing) ? existing : []; + list.push(payload); + atomicWrite(inboxPath, JSON.stringify(list, null, 2)); + var verify = readJson(inboxPath, []); + if (Array.isArray(verify) && verify.some(function (m) { return m && m.messageId === messageId; })) { + return { deliveredToInbox: true, messageId: messageId }; + } + // Verification failed (concurrent write overwrote us) — retry + } catch (e) { + lastErr = e; + if (attempt === 7) throw e; + } } - return { deliveredToInbox: true, messageId }; + // If all retries exhausted without verification success, die + die('Inbox write verification failed after retries' + (lastErr ? ': ' + formatError(lastErr) : '')); } function reviewApprove(paths, teamName, taskId, flags) {