Skip to content

Commit 7af4025

Browse files
waleedlatif1claude
andcommitted
fix(execution): restore running entries when reconnection is interrupted by navigation
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 61a6b18 commit 7af4025

File tree

1 file changed

+24
-5
lines changed

1 file changed

+24
-5
lines changed

apps/sim/app/workspace/[workspaceId]/w/[workflowId]/hooks/use-workflow-execution.ts

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2137,10 +2137,17 @@ export function useWorkflowExecution() {
21372137
includeStartConsoleEntry: true,
21382138
})
21392139

2140+
// Save original running entries so we can restore them if reconnection is interrupted.
2141+
// This ensures the next mount can retry reconnection.
2142+
const originalEntries = runningEntries
2143+
.filter((e) => e.executionId === executionId)
2144+
.map((e) => ({ ...e }))
2145+
21402146
// Defer clearing old entries until the first reconnection event arrives.
21412147
// This keeps hydrated entries visible during the network round-trip,
21422148
// avoiding a flash of empty console.
21432149
let cleared = false
2150+
let reconnectionComplete = false
21442151
const clearOnce = () => {
21452152
if (!cleared) {
21462153
cleared = true
@@ -2169,12 +2176,14 @@ export function useWorkflowExecution() {
21692176
},
21702177
onExecutionCompleted: () => {
21712178
clearOnce()
2179+
reconnectionComplete = true
21722180
setCurrentExecutionId(reconnectWorkflowId, null)
21732181
setIsExecuting(reconnectWorkflowId, false)
21742182
setActiveBlocks(reconnectWorkflowId, new Set())
21752183
},
21762184
onExecutionError: (data) => {
21772185
clearOnce()
2186+
reconnectionComplete = true
21782187
setCurrentExecutionId(reconnectWorkflowId, null)
21792188
setIsExecuting(reconnectWorkflowId, false)
21802189
setActiveBlocks(reconnectWorkflowId, new Set())
@@ -2187,6 +2196,7 @@ export function useWorkflowExecution() {
21872196
},
21882197
onExecutionCancelled: () => {
21892198
clearOnce()
2199+
reconnectionComplete = true
21902200
setCurrentExecutionId(reconnectWorkflowId, null)
21912201
setIsExecuting(reconnectWorkflowId, false)
21922202
setActiveBlocks(reconnectWorkflowId, new Set())
@@ -2198,9 +2208,10 @@ export function useWorkflowExecution() {
21982208
},
21992209
})
22002210
.catch((error) => {
2211+
reconnectionComplete = true
22012212
logger.warn('Execution reconnection failed', { executionId, error })
22022213
clearExecutionEntries(executionId)
2203-
for (const entry of runningEntries.filter((e) => e.executionId === executionId)) {
2214+
for (const entry of originalEntries) {
22042215
addConsole({
22052216
workflowId: entry.workflowId,
22062217
blockId: entry.blockId,
@@ -2219,10 +2230,18 @@ export function useWorkflowExecution() {
22192230

22202231
return () => {
22212232
executionStream.cancel(reconnectWorkflowId)
2222-
// Reset execution state so the SPA guard doesn't block the next reconnection
2223-
// attempt when the user navigates back to this workflow.
2224-
// The cancel above causes an AbortError which is swallowed by
2225-
// isClientDisconnectError, so the .catch() block never fires.
2233+
2234+
// If reconnection was interrupted (clearOnce fired but no terminal event arrived),
2235+
// restore the original running entries so the next mount can retry.
2236+
// cancel() causes an AbortError which is swallowed by isClientDisconnectError,
2237+
// so the .catch() block never fires — we must handle cleanup here.
2238+
if (cleared && !reconnectionComplete) {
2239+
clearExecutionEntries(executionId)
2240+
for (const entry of originalEntries) {
2241+
addConsole(entry)
2242+
}
2243+
}
2244+
22262245
setCurrentExecutionId(reconnectWorkflowId, null)
22272246
setIsExecuting(reconnectWorkflowId, false)
22282247
setActiveBlocks(reconnectWorkflowId, new Set())

0 commit comments

Comments
 (0)