fix: address critical race conditions in auto-resume queue

1. Remove autoResumeProcessing reset in clearAutoResumeQueue()
   - Setting the flag to false created a race condition allowing concurrent
     processAutoResumeQueue() instances
   - The generation counter is sufficient to abort stale processing runs
   - Fixes potential duplicate resume attempts

2. Add error handling in resumeAllPendingClaude()
   - Wrap resumeTerminalClaudeSession() in try/catch
   - Ensures one terminal's error doesn't block remaining terminals
   - Improves robustness of manual "Resume All" button

Co-Authored-By: Claude Opus 4.6 <[email protected]>
This commit is contained in:
AndyMik90
2026-02-20 12:37:12 +01:00
co-authored by Claude Opus 4.6
parent cb1363c994
commit 6d2b53ec6a
@@ -160,7 +160,10 @@ export function clearAutoResumeQueue(): void {
clearTimeout(autoResumeTimer);
autoResumeTimer = null;
}
autoResumeProcessing = false;
// Don't reset autoResumeProcessing here - the generation counter is sufficient
// to abort stale processing runs. Resetting the flag here creates a race condition
// where clearAutoResumeQueue() could allow a new processAutoResumeQueue() to start
// before the aborted one has fully exited.
autoResumeGeneration++; // Increment generation to abort any in-flight processing
debugLog('[AutoResume] Queue cleared');
}
@@ -683,8 +686,13 @@ export const useTerminalStore = create<TerminalState>((set, get) => ({
for (let i = 0; i < pendingTerminals.length; i++) {
const terminal = pendingTerminals[i];
debugLog(`[TerminalStore] Activating deferred Claude resume for terminal: ${terminal.id}`);
resumeTerminalClaudeSession(terminal.id);
try {
debugLog(`[TerminalStore] Activating deferred Claude resume for terminal: ${terminal.id}`);
resumeTerminalClaudeSession(terminal.id);
} catch (error) {
// Log error and continue processing remaining terminals
debugError(`[TerminalStore] Error resuming terminal ${terminal.id}:`, error);
}
// Wait before processing next terminal (staggered delay)
if (i < pendingTerminals.length - 1) {
@@ -813,3 +821,7 @@ export async function restoreTerminalSessions(projectPath: string): Promise<void
restoringProjects.delete(projectPath);
}
}
// NOTE: HMR cleanup for auto-resume queue state would be beneficial during development
// to clear timers on hot reload, but requires augmenting ImportMeta types in vite-env.d.ts.
// The generation counter provides sufficient protection against stale processing runs.