From 7204df600d9c9b2dc3c8ac2bc635082d207f72e6 Mon Sep 17 00:00:00 2001 From: Theodore Nastos <15264814+theonastos@users.noreply.github.com> Date: Tue, 29 Sep 2026 14:50:29 +0000 Subject: [PATCH] fix(editor): Do not run the workflow when the save before execute fails (#39763) --- .../app/composables/useRunWorkflow.test.ts | 31 +++++++++++++++++++ .../src/app/composables/useRunWorkflow.ts | 4 +-- .../logs/components/LogsOverviewPanel.test.ts | 1 + 3 files changed, 34 insertions(+), 2 deletions(-) diff --git a/packages/frontend/editor-ui/src/app/composables/useRunWorkflow.test.ts b/packages/frontend/editor-ui/src/app/composables/useRunWorkflow.test.ts index 435728194d2..44eb861a47e 100644 --- a/packages/frontend/editor-ui/src/app/composables/useRunWorkflow.test.ts +++ b/packages/frontend/editor-ui/src/app/composables/useRunWorkflow.test.ts @@ -466,6 +466,22 @@ describe('useRunWorkflow({ router })', () => { await runWorkflow({}); expect(workflowSaving.saveCurrentWorkflow).toHaveBeenCalledTimes(1); + expect(workflowsStore.runWorkflow).toHaveBeenCalledTimes(1); + }); + + it('should not run when the save before execute fails with autosave enabled', async () => { + vi.spyOn(settingsStore, 'isAutosaveEnabled', 'get').mockReturnValue(true); + vi.mocked(uiStore).stateIsDirty = true; + vi.mocked(workflowsStore).isWorkflowSaved = { '123': true }; + + const workflowSaving = useWorkflowSaving({ router }); + vi.mocked(workflowSaving.saveCurrentWorkflow).mockResolvedValueOnce(false); + const { runWorkflow } = useRunWorkflow({ router }); + const result = await runWorkflow({}); + + expect(workflowSaving.saveCurrentWorkflow).toHaveBeenCalledTimes(1); + expect(workflowsStore.runWorkflow).not.toHaveBeenCalled(); + expect(result).toBeUndefined(); }); it('should prompt the user and save when they confirm if autosave is disabled and state is dirty (ADO-5328)', async () => { @@ -515,6 +531,21 @@ describe('useRunWorkflow({ router })', () => { expect(workflowSaving.saveCurrentWorkflow).toHaveBeenCalledTimes(1); }); + + it('should not run a new workflow when its first save fails', async () => { + vi.spyOn(settingsStore, 'isAutosaveEnabled', 'get').mockReturnValue(false); + vi.mocked(uiStore).stateIsDirty = false; + vi.mocked(workflowsStore).isWorkflowSaved = {}; + + const workflowSaving = useWorkflowSaving({ router }); + vi.mocked(workflowSaving.saveCurrentWorkflow).mockResolvedValueOnce(false); + const { runWorkflow } = useRunWorkflow({ router }); + const result = await runWorkflow({}); + + expect(workflowSaving.saveCurrentWorkflow).toHaveBeenCalledTimes(1); + expect(workflowsStore.runWorkflow).not.toHaveBeenCalled(); + expect(result).toBeUndefined(); + }); }); describe('scoped workflow document store (eval-loop reruns)', () => { diff --git a/packages/frontend/editor-ui/src/app/composables/useRunWorkflow.ts b/packages/frontend/editor-ui/src/app/composables/useRunWorkflow.ts index 5542f72d91f..13c1ddb5c2d 100644 --- a/packages/frontend/editor-ui/src/app/composables/useRunWorkflow.ts +++ b/packages/frontend/editor-ui/src/app/composables/useRunWorkflow.ts @@ -175,15 +175,15 @@ export function useRunWorkflow(useRunWorkflowOpts: { if (response !== MODAL_CONFIRM) { return undefined; } + } + if (isNewWorkflow || uiStore.stateIsDirty) { const saved = await workflowSaving.saveCurrentWorkflow({ id: workflowDocumentStore.value.workflowId, }); if (!saved) { return undefined; } - } else if (isNewWorkflow || (uiStore.stateIsDirty && settingsStore.isAutosaveEnabled)) { - await workflowSaving.saveCurrentWorkflow({ id: workflowDocumentStore.value.workflowId }); } const workflowData = workflowDocumentStore.value.serialize(); diff --git a/packages/frontend/editor-ui/src/features/execution/logs/components/LogsOverviewPanel.test.ts b/packages/frontend/editor-ui/src/features/execution/logs/components/LogsOverviewPanel.test.ts index 5694af39530..961329c1816 100644 --- a/packages/frontend/editor-ui/src/features/execution/logs/components/LogsOverviewPanel.test.ts +++ b/packages/frontend/editor-ui/src/features/execution/logs/components/LogsOverviewPanel.test.ts @@ -319,6 +319,7 @@ describe('LogsOverviewPanel', () => { it('should trigger partial execution if the button is clicked', async () => { const spyRun = vi.spyOn(workflowsStore, 'runWorkflow'); + workflowsStore.isWorkflowSaved = { 'test-workflow-id': true }; const logs = createLogTree( createTestWorkflowObject(aiManualWorkflow),