diff --git a/packages/@n8n/config/src/configs/executions.config.ts b/packages/@n8n/config/src/configs/executions.config.ts index c9b8f45b15d..3add6e45dec 100644 --- a/packages/@n8n/config/src/configs/executions.config.ts +++ b/packages/@n8n/config/src/configs/executions.config.ts @@ -154,8 +154,4 @@ export class ExecutionsConfig { /** Whether to save execution data for manual executions. This default can be overridden at a workflow level. */ @Env('EXECUTIONS_DATA_SAVE_MANUAL_EXECUTIONS') saveDataManualExecutions: boolean = true; - - /** Whether scheduled executions receive a deduplication key enforced by a unique DB index. */ - @Env('N8N_SCHEDULED_EXECUTION_DEDUPLICATION_ENABLED') - scheduledExecutionDeduplicationEnabled: boolean = false; } diff --git a/packages/@n8n/config/test/config.test.ts b/packages/@n8n/config/test/config.test.ts index b367312aed9..0bd0aa2f1c8 100644 --- a/packages/@n8n/config/test/config.test.ts +++ b/packages/@n8n/config/test/config.test.ts @@ -3,7 +3,7 @@ import { tmpdir } from 'node:os'; import path from 'node:path'; import type { DatabaseConfig } from '../src/index'; -import { ExecutionsConfig, GlobalConfig, SSRF_DEFAULT_BLOCKED_IP_RANGES } from '../src/index'; +import { GlobalConfig, SSRF_DEFAULT_BLOCKED_IP_RANGES } from '../src/index'; const { readFileSyncMock } = vi.hoisted(() => ({ readFileSyncMock: vi.fn(), @@ -470,7 +470,6 @@ describe('GlobalConfig', () => { saveDataOnSuccess: 'all', saveExecutionProgress: false, saveDataManualExecutions: true, - scheduledExecutionDeduplicationEnabled: false, }, diagnostics: { enabled: true, @@ -868,20 +867,4 @@ describe('GlobalConfig', () => { expect(config.endpoints.health).toEqual('/api/v1/health'); }); }); - - describe('ExecutionsConfig', () => { - it('should default scheduledExecutionDeduplicationEnabled to false', () => { - process.env = {}; - const config = Container.get(ExecutionsConfig); - expect(config.scheduledExecutionDeduplicationEnabled).toBe(false); - }); - - it('should enable scheduledExecutionDeduplicationEnabled when env var is set to true', () => { - process.env = { - N8N_SCHEDULED_EXECUTION_DEDUPLICATION_ENABLED: 'true', - }; - const config = Container.get(ExecutionsConfig); - expect(config.scheduledExecutionDeduplicationEnabled).toBe(true); - }); - }); }); diff --git a/packages/nodes-base/nodes/Schedule/ScheduleTrigger.node.ts b/packages/nodes-base/nodes/Schedule/ScheduleTrigger.node.ts index 8e906d5f39e..221a1868c08 100644 --- a/packages/nodes-base/nodes/Schedule/ScheduleTrigger.node.ts +++ b/packages/nodes-base/nodes/Schedule/ScheduleTrigger.node.ts @@ -1,5 +1,3 @@ -import { ExecutionsConfig } from '@n8n/config'; -import { Container } from '@n8n/di'; import { sendAt } from 'cron'; import moment from 'moment-timezone'; import type { @@ -446,12 +444,6 @@ export class ScheduleTrigger implements INodeType { const workflowId = this.getWorkflow().id; const nodeId = this.getNode().id; - const configDedupEnabled = - Container.get(ExecutionsConfig).scheduledExecutionDeduplicationEnabled; - // The workflowId should always be defined, but if it isn't we skip - // the deduplication key. - const dedupEnabled = configDedupEnabled && Boolean(workflowId); - const executeTrigger = ( recurrence: IRecurrenceRule, skipRecurrenceCheck = false, @@ -477,8 +469,10 @@ export class ScheduleTrigger implements INodeType { Timezone: `${timezone} (UTC${momentTz.format('Z')})`, }; + // The workflowId should always be defined, but if it isn't we skip + // the deduplication key. const deduplicationKey = - dedupEnabled && scheduledTime + workflowId && scheduledTime ? `${workflowId}:${nodeId}:${scheduledTime.toISOString()}` : undefined; diff --git a/packages/nodes-base/nodes/Schedule/test/ScheduleTrigger.node.test.ts b/packages/nodes-base/nodes/Schedule/test/ScheduleTrigger.node.test.ts index 2b01e73f38d..decf7bb4d70 100644 --- a/packages/nodes-base/nodes/Schedule/test/ScheduleTrigger.node.test.ts +++ b/packages/nodes-base/nodes/Schedule/test/ScheduleTrigger.node.test.ts @@ -1,5 +1,3 @@ -import { ExecutionsConfig } from '@n8n/config'; -import { Container } from '@n8n/di'; import * as n8nWorkflow from 'n8n-workflow'; import { testTriggerNode } from '@test/nodes/TriggerHelpers'; @@ -222,19 +220,7 @@ describe('ScheduleTrigger', () => { }); describe('deduplication key', () => { - const executionsConfig = Container.get(ExecutionsConfig); - - beforeEach(() => { - executionsConfig.scheduledExecutionDeduplicationEnabled = false; - }); - - afterEach(() => { - executionsConfig.scheduledExecutionDeduplicationEnabled = false; - }); - - it('should emit a deduplication key when the feature flag is enabled', async () => { - executionsConfig.scheduledExecutionDeduplicationEnabled = true; - + it('should emit a deduplication key for scheduled executions', async () => { const workflowId = 'wf-123'; const nodeId = 'node-456'; const { emit } = await testTriggerNode(ScheduleTrigger, { @@ -269,8 +255,6 @@ describe('ScheduleTrigger', () => { }); it('should not emit a deduplication key for manual executions', async () => { - executionsConfig.scheduledExecutionDeduplicationEnabled = true; - const { emit, manualTriggerFunction } = await testTriggerNode(ScheduleTrigger, { mode: 'manual', timezone,