From 94137d08dbfc227f84526a6937ebaec0de6f5ccb Mon Sep 17 00:00:00 2001 From: Alex Grozav Date: Wed, 10 Dec 2025 10:31:19 +0000 Subject: [PATCH] fix(editor): Allow running webhook workflow even when a node has error (#22239) Co-authored-by: Danny Martini --- .../app/composables/useRunWorkflow.test.ts | 6 ++-- .../src/app/composables/useRunWorkflow.ts | 5 --- .../playwright/tests/e2e/api/webhook.spec.ts | 36 +++++++++++++++++++ 3 files changed, 38 insertions(+), 9 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 c34fed6301f..850a2ceb6f0 100644 --- a/packages/frontend/editor-ui/src/app/composables/useRunWorkflow.test.ts +++ b/packages/frontend/editor-ui/src/app/composables/useRunWorkflow.test.ts @@ -219,7 +219,7 @@ describe('useRunWorkflow({ router })', () => { expect(workflowsStore.executionWaitingForWebhook).toBe(false); }); - it('should prevent running a webhook-based workflow that has issues', async () => { + it('should not prevent running a webhook-based workflow that has issues', async () => { const { runWorkflowApi } = useRunWorkflow({ router }); vi.mocked(workflowsStore).nodesIssuesExist = true; vi.mocked(workflowsStore).runWorkflow.mockResolvedValue({ @@ -227,9 +227,7 @@ describe('useRunWorkflow({ router })', () => { waitingForWebhook: true, }); - await expect(runWorkflowApi({} as IStartRunData)).rejects.toThrow( - 'workflowRun.showError.resolveOutstandingIssues', - ); + await expect(runWorkflowApi({} as IStartRunData)).resolves.not.toThrow(); vi.mocked(workflowsStore).nodesIssuesExist = false; }); diff --git a/packages/frontend/editor-ui/src/app/composables/useRunWorkflow.ts b/packages/frontend/editor-ui/src/app/composables/useRunWorkflow.ts index 1fb80d8e1b5..29f1d2a1ec7 100644 --- a/packages/frontend/editor-ui/src/app/composables/useRunWorkflow.ts +++ b/packages/frontend/editor-ui/src/app/composables/useRunWorkflow.ts @@ -113,11 +113,6 @@ export function useRunWorkflow(useRunWorkflowOpts: { workflowState.setActiveExecutionId(response.executionId); } - if (response.waitingForWebhook === true && workflowsStore.nodesIssuesExist) { - workflowState.setActiveExecutionId(undefined); - throw new Error(i18n.baseText('workflowRun.showError.resolveOutstandingIssues')); - } - if (response.waitingForWebhook === true) { workflowsStore.executionWaitingForWebhook = true; } diff --git a/packages/testing/playwright/tests/e2e/api/webhook.spec.ts b/packages/testing/playwright/tests/e2e/api/webhook.spec.ts index 13613b9d737..27637132dee 100644 --- a/packages/testing/playwright/tests/e2e/api/webhook.spec.ts +++ b/packages/testing/playwright/tests/e2e/api/webhook.spec.ts @@ -225,6 +225,42 @@ test.describe.skip('Webhook Trigger node', () => { }); expect(successResponse.ok()).toBe(true); }); + + test('CAT-1253-bug-cant-run-workflow-when-unconnected-nodes-have-errors', async ({ n8n }) => { + const webhookPath = nanoid(); + + // Add Webhook node + await n8n.canvas.addNode('Webhook'); + await n8n.ndv.setupHelper.webhook({ + httpMethod: 'GET', + path: webhookPath, + }); + await n8n.ndv.close(); + + // Add No Operation node - it will connect automatically since Webhook node is in context + await n8n.canvas.nodeByName('Webhook').click(); + await n8n.canvas.addNode('No Operation, do nothing', { closeNDV: true }); + + // Verify connection was created + await expect(n8n.canvas.nodeConnections()).toHaveCount(1); + + // Add HTTP Request node (unconnected, which will have an error) + await n8n.canvas.deselectAll(); + await n8n.canvas.addNode('HTTP Request', { closeNDV: true }); + + // Verify we now have 3 nodes but still only 1 connection + await expect(n8n.canvas.getCanvasNodes()).toHaveCount(3); + await expect(n8n.canvas.nodeConnections()).toHaveCount(1); + + // Execute the workflow + await n8n.canvas.clickExecuteWorkflowButton(); + + // Assert that webhook is waiting for trigger + await expect(n8n.canvas.waitingForTriggerEvent()).toBeVisible(); + + // Assert that no error toast appeared + await expect(n8n.notifications.getErrorNotifications()).toHaveCount(0); + }); }); async function addEditFieldsNode(n8n: n8nPage): Promise {