From 1f434b43c5b6f71463c05f0cbcd0f6c901163c7d Mon Sep 17 00:00:00 2001 From: sim Date: Thu, 15 Oct 2026 17:30:21 +0200 Subject: [PATCH] fix(core): Turn off expression spans by default N8N_EXPRESSION_ENGINE_TRACES_ENABLED now defaults to false. Set it to true to create expression spans again. https://linear.app/n8n/issue/GOV-234 Co-Authored-By: Claude Opus 5.5 --- .../configs/__tests__/expression-engine.config.test.ts | 4 ++-- .../@n8n/config/src/configs/expression-engine.config.ts | 9 +++++---- packages/@n8n/config/test/config.test.ts | 2 +- .../__tests__/expression-observability.provider.test.ts | 6 +++--- 4 files changed, 11 insertions(+), 10 deletions(-) diff --git a/packages/@n8n/config/src/configs/__tests__/expression-engine.config.test.ts b/packages/@n8n/config/src/configs/__tests__/expression-engine.config.test.ts index e1261f0f963..97f6ee2a356 100644 --- a/packages/@n8n/config/src/configs/__tests__/expression-engine.config.test.ts +++ b/packages/@n8n/config/src/configs/__tests__/expression-engine.config.test.ts @@ -156,8 +156,8 @@ describe('ExpressionEngineConfig', () => { expect(Container.get(ExpressionEngineConfig).observabilityEnabled).toBe(true); }); - test('tracesEnabled defaults to true', () => { - expect(Container.get(ExpressionEngineConfig).tracesEnabled).toBe(true); + test('tracesEnabled defaults to false', () => { + expect(Container.get(ExpressionEngineConfig).tracesEnabled).toBe(false); }); test('slowEvaluationThresholdMs defaults to 50', () => { diff --git a/packages/@n8n/config/src/configs/expression-engine.config.ts b/packages/@n8n/config/src/configs/expression-engine.config.ts index 1fc924c2155..35c151e5b13 100644 --- a/packages/@n8n/config/src/configs/expression-engine.config.ts +++ b/packages/@n8n/config/src/configs/expression-engine.config.ts @@ -65,12 +65,13 @@ export class ExpressionEngineConfig { observabilityEnabled: boolean = true; /** - * Whether to emit OpenTelemetry spans for expression evaluation. - * Slow evaluations (>slowEvaluationThresholdMs) and errors always emit a span. - * Healthy-path evaluations are sampled at tracesSampleRate. + * Whether n8n sends OpenTelemetry spans for expression evaluations when `N8N_OTEL_ENABLED` + * is true. n8n creates a span for each evaluation that fails or takes longer than + * `N8N_EXPRESSION_ENGINE_SLOW_EVAL_THRESHOLD_MS`, and samples the rest at + * `N8N_EXPRESSION_ENGINE_TRACES_SAMPLE_RATE`. */ @Env('N8N_EXPRESSION_ENGINE_TRACES_ENABLED') - tracesEnabled: boolean = true; + tracesEnabled: boolean = false; /** Threshold in ms above which an evaluation is considered "slow" and gets a span. */ @Env('N8N_EXPRESSION_ENGINE_SLOW_EVAL_THRESHOLD_MS', z.number({ coerce: true }).positive()) diff --git a/packages/@n8n/config/test/config.test.ts b/packages/@n8n/config/test/config.test.ts index 30e813d3ffc..d50e8e96ed2 100644 --- a/packages/@n8n/config/test/config.test.ts +++ b/packages/@n8n/config/test/config.test.ts @@ -699,7 +699,7 @@ describe('GlobalConfig', () => { bridgeTimeout: 5000, bridgeMemoryLimit: 128, observabilityEnabled: true, - tracesEnabled: true, + tracesEnabled: false, slowEvaluationThresholdMs: 50, tracesSampleRate: 0.0, allowWebhookIsolateSkip: true, diff --git a/packages/cli/src/expression-observability/__tests__/expression-observability.provider.test.ts b/packages/cli/src/expression-observability/__tests__/expression-observability.provider.test.ts index 8decf2e1d42..44161fd38d9 100644 --- a/packages/cli/src/expression-observability/__tests__/expression-observability.provider.test.ts +++ b/packages/cli/src/expression-observability/__tests__/expression-observability.provider.test.ts @@ -23,9 +23,9 @@ const startSpanMock = vi.fn().mockReturnValue({ function buildConfig(overrides: Partial = {}): ExpressionEngineConfig { const config = new ExpressionEngineConfig(); - // The provider is a no-op unless engine === 'vm'. Default tests to the active - // engine so shared assertions exercise the real code path. - return Object.assign(config, { engine: 'vm' as const, ...overrides }); + // The provider is a no-op unless engine is 'vm', and spans are off by default. + // Turn both on so shared assertions exercise the real code path. + return Object.assign(config, { engine: 'vm' as const, tracesEnabled: true, ...overrides }); } function buildLogger(): Logger {