Skip to content

fix(autorun): resolve paused batch session for resume/skip/abort#715

Closed
nehaaprasad wants to merge 1 commit intoRunMaestro:mainfrom
nehaaprasad:fix/aut-bann-sty
Closed

fix(autorun): resolve paused batch session for resume/skip/abort#715
nehaaprasad wants to merge 1 commit intoRunMaestro:mainfrom
nehaaprasad:fix/aut-bann-sty

Conversation

@nehaaprasad
Copy link
Copy Markdown
Contributor

@nehaaprasad nehaaprasad commented Apr 3, 2026

summary

  • Fix error banner staying after Resume by clearing the same batch session the UI shows.

Changes

  • src/renderer/hooks/batch/useBatchHandlers.ts — resolve paused session (prefer active session, then any errorPaused) for resume/skip/abort

fix : #707

Summary by CodeRabbit

Release Notes

  • Bug Fixes
    • Enhanced error recovery in batch processing. When pausing on error, the system now intelligently selects which batch to resume from—prioritizing the currently active one, then any paused batch, then the first active batch for more predictable operation handling.

@greptile-apps
Copy link
Copy Markdown

greptile-apps bot commented Apr 3, 2026

Greptile Summary

This PR fixes a bug where the error banner in the Auto Run panel persisted after clicking Resume, Skip, or Abort — caused by the handlers resolving the wrong batch session ID via the generic activeBatchSessionIds[0] list (which tracks isRunning, not errorPaused).

The fix introduces resolveBatchSessionIdForPausedError, which reads errorPaused directly from the Zustand batchStore (consistent with how RightPanel.tsx and AutoRun.tsx subscribe to the same field, bypassing the UPDATE_PROGRESS path that drops error-state fields).

Key changes:

  • handleSkipCurrentDocument, handleResumeAfterError, and handleAbortBatchOnError now use the new resolver instead of blindly picking activeBatchSessionIds[0]
  • The resolver correctly prioritises: (1) active session with errorPaused, (2) any session with errorPaused, (3) first active batch session, (4) active session ID
  • Uses useBatchStore.getState() at call-time (not as a reactive subscription) to avoid stale closures — the established pattern in this codebase for accessing errorPaused which is dropped by updateBatchStateAndBroadcast

Issue flagged:

Confidence Score: 4/5

Safe to merge; the fix correctly resolves the primary bug for both single and multi-session scenarios.

The change is small and targeted, uses the established useBatchStore.getState() pattern already in RightPanel.tsx/AutoRun.tsx, and correctly prioritises the active session. A minor concern exists around the "any paused session" fallback potentially acting on a background session, but normal UI gating makes this unreachable in practice.

src/renderer/hooks/batch/useBatchHandlers.ts — specifically the branch-2 fallback in resolveBatchSessionIdForPausedError

Important Files Changed

Filename Overview
src/renderer/hooks/batch/useBatchHandlers.ts Introduces resolveBatchSessionIdForPausedError to fix resume/skip/abort acting on the wrong batch session; logic is sound for the primary case but the "any paused session" fallback could theoretically operate on a background session invisible to the user.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[User clicks Resume / Skip / Abort in UI] --> B[resolveBatchSessionIdForPausedError called]
    B --> C{activeSession has errorPaused?}
    C -- Yes --> D[Return activeSession.id]
    C -- No --> E{Any session in batchRunStates has errorPaused?}
    E -- Yes --> F[Return that session id - may not match UI]
    E -- No --> G{activeBatchSessionIds non-empty?}
    G -- Yes --> H[Return activeBatchSessionIds 0 - pre-existing fallback]
    G -- No --> I[Return activeSession.id - last resort]
    D --> J[Call action on resolved sessionId]
    F --> J
    H --> J
    I --> J
    J --> K[handleClearAgentError on same sessionId]
Loading

Reviews (1): Last reviewed commit: "fix(autorun): resolve paused batch sessi..." | Re-trigger Greptile

Comment on lines +50 to +53
const pausedId = Object.keys(batchRunStates).find(
(id) => batchRunStates[id]?.errorPaused
);
if (pausedId) return pausedId;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Fallback branch may operate on a hidden/background session

Branch 2 searches all batchRunStates for any session with errorPaused === true, regardless of whether that session is currently active (shown in the UI). The Resume/Skip/Abort buttons in RightPanel.tsx and AutoRun.tsx are only rendered when the active session has errorPaused, meaning in normal UI flow this branch can only be reached if the active session doesn't have errorPaused — in which case no error banner is visible and these handlers shouldn't fire at all.

In an edge case (e.g., programmatic invocation), this branch could silently call resumeAfterError/skipCurrentDocument/abortBatchOnError on a background session the user isn't looking at, which could corrupt its state unexpectedly.

A more conservative fallback would skip branch 2 entirely and let the function fall through to the existing activeBatchSessionIds[0] / activeSession safety net:

function resolveBatchSessionIdForPausedError(
	batchRunStates: Record<string, BatchRunState>,
	activeSessionId: string | undefined,
	activeBatchSessionIds: string[]
): string | undefined {
	if (activeSessionId && batchRunStates[activeSessionId]?.errorPaused) {
		return activeSessionId;
	}
	if (activeBatchSessionIds.length > 0) return activeBatchSessionIds[0];
	return activeSessionId;
}

The root cause of #707 (wrong session chosen from activeBatchSessionIds) is fully addressed by branch 1 alone, since the RightPanel/AutoRun UI is always keyed to the active session's state.

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 3, 2026

📝 Walkthrough

Walkthrough

A helper function was added to intelligently resolve the target batch session ID when handling paused-on-error states, implementing fallback logic to prefer the active session if paused, then any paused session, then the first active session, then the active session ID itself. Three batch handlers were updated to use this helper instead of directly selecting session IDs.

Changes

Cohort / File(s) Summary
Batch Handler Session Resolution
src/renderer/hooks/batch/useBatchHandlers.ts
Added resolveBatchSessionIdForPausedError() helper function to intelligently select batch session ID when handling paused-on-error state using a preference hierarchy. Updated handleSkipCurrentDocument, handleResumeAfterError, and handleAbortBatchOnError to use the helper. Added useBatchStore import for accessing batch run states.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

Poem

🐰 A batch of sessions, paused in their tracks,
Now we choose wisely which one gets back,
With fallback logic, so clever and neat,
The perfect session makes error-handling sweet! 🎯

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change—resolving the correct paused batch session for resume/skip/abort operations to fix the error banner issue.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/renderer/hooks/batch/useBatchHandlers.ts`:
- Around line 42-56: The resolver resolveBatchSessionIdForPausedError currently
falls back to a running/selected session which lets skip/resume/abort actions
target the wrong batch; change it to return undefined when no batchRunStates
entry has errorPaused (remove the activeBatchSessionIds[0]/activeSessionId
fallbacks) so paused-error actions fail closed, then update the three callers
that pass the now-unused third argument (the activeBatchSessionIds array) to
stop passing it and handle an undefined sessionId safely (abort/skip/resume
should no-op or surface an error). Optionally, for the stronger fix thread the
exact banner's sessionId into the handlers instead of inferring it from
resolveBatchSessionIdForPausedError.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: d975ddbc-9ed7-4704-b26c-43e13c095fcf

📥 Commits

Reviewing files that changed from the base of the PR and between 6e467f4 and c724297.

📒 Files selected for processing (1)
  • src/renderer/hooks/batch/useBatchHandlers.ts

Comment on lines +42 to +56
function resolveBatchSessionIdForPausedError(
batchRunStates: Record<string, BatchRunState>,
activeSessionId: string | undefined,
activeBatchSessionIds: string[]
): string | undefined {
if (activeSessionId && batchRunStates[activeSessionId]?.errorPaused) {
return activeSessionId;
}
const pausedId = Object.keys(batchRunStates).find(
(id) => batchRunStates[id]?.errorPaused
);
if (pausedId) return pausedId;
if (activeBatchSessionIds.length > 0) return activeBatchSessionIds[0];
return activeSessionId;
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Make paused-error actions fail closed instead of guessing another session.

If Line 50 finds no paused batch, Line 54 and Line 55 still return a running or merely selected session, so Line 643, Line 654, and Line 665 can skip/resume/abort the wrong batch and clear the wrong agent error. And if more than one batch is paused, the current find(...) still resolves by store key order, not by the banner the user clicked. At minimum, return undefined when nothing is errorPaused; ideally, pass the displayed banner's sessionId into these handlers instead of inferring it here.

🛠️ Minimal safe fix
function resolveBatchSessionIdForPausedError(
	batchRunStates: Record<string, BatchRunState>,
-	activeSessionId: string | undefined,
-	activeBatchSessionIds: string[]
+	activeSessionId: string | undefined
): string | undefined {
	if (activeSessionId && batchRunStates[activeSessionId]?.errorPaused) {
		return activeSessionId;
	}
-	const pausedId = Object.keys(batchRunStates).find(
-		(id) => batchRunStates[id]?.errorPaused
-	);
-	if (pausedId) return pausedId;
-	if (activeBatchSessionIds.length > 0) return activeBatchSessionIds[0];
-	return activeSessionId;
+	return Object.keys(batchRunStates).find((id) => batchRunStates[id]?.errorPaused);
}

Then drop the now-unused third argument at Line 643, Line 654, and Line 665. If the UI can surface more than one paused batch, the stronger fix is to thread the clicked banner's sessionId into these handlers instead of inferring it here.

Also applies to: 643-669

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/renderer/hooks/batch/useBatchHandlers.ts` around lines 42 - 56, The
resolver resolveBatchSessionIdForPausedError currently falls back to a
running/selected session which lets skip/resume/abort actions target the wrong
batch; change it to return undefined when no batchRunStates entry has
errorPaused (remove the activeBatchSessionIds[0]/activeSessionId fallbacks) so
paused-error actions fail closed, then update the three callers that pass the
now-unused third argument (the activeBatchSessionIds array) to stop passing it
and handle an undefined sessionId safely (abort/skip/resume should no-op or
surface an error). Optionally, for the stronger fix thread the exact banner's
sessionId into the handlers instead of inferring it from
resolveBatchSessionIdForPausedError.

@jSydorowicz21
Copy link
Copy Markdown
Contributor

@nehaaprasad Please look into the feedback from coderabbit and greptile and address as needed

Copy link
Copy Markdown
Collaborator

@pedramamini pedramamini left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review

The core idea is correct — reading errorPaused from the batch store to resolve the right session fixes the stale banner bug. One issue worth addressing:

Fallback to non-error-paused sessions undermines the fix

The fallback chain in resolveBatchSessionIdForPausedError goes:

  1. activeSessionId if errorPaused
  2. Any session with errorPaused
  3. activeBatchSessionIds[0] ❌ — may not be error-paused
  4. activeSessionId ❌ — may not be error-paused

Steps 3 and 4 can route skipCurrentDocument/resumeAfterError/abortBatchOnError to a session that isn't paused on error. Since these handlers are specifically for error recovery, the function should return undefined when nothing is actually error-paused and let the existing if (!sessionId) return guard handle it.

Suggested change — drop the non-error-paused fallbacks and the now-unnecessary activeBatchSessionIds parameter:

function resolveBatchSessionIdForPausedError(
	batchRunStates: Record<string, BatchRunState>,
	activeSessionId: string | undefined
): string | undefined {
	if (activeSessionId && batchRunStates[activeSessionId]?.errorPaused) {
		return activeSessionId;
	}
	return Object.keys(batchRunStates).find(
		(id) => batchRunStates[id]?.errorPaused
	);
}

This also lets you remove activeBatchSessionIds from the three useCallback dependency arrays.

Minor

  • Consider adding a // Reads batchRunStates imperatively at call time comment in each callback to signal the intentional store-outside-subscription pattern (matches the style used in onComplete at line 184).

@pedramamini
Copy link
Copy Markdown
Collaborator

Thanks for the contribution @nehaaprasad! Great catch on the error banner persistence issue — the root cause analysis of needing to check errorPaused in the batch store was spot on.

I've merged your changes into fix/aut-bann-sty on the main repo with a small refinement: removed the non-error-paused fallbacks so skip/resume/abort only target sessions that are actually paused on error (see the review comment above for rationale). Updated tests to match.

Closing this PR in favor of the updated branch — your work is preserved in the commit history. Thanks again!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bug: Auto Run error banner stays visible after clicking Resume

3 participants