From e228ee968e8a8f8652e5370b81d2ef39c8d42f75 Mon Sep 17 00:00:00 2001 From: "n8n-cat-bot[bot]" <283985454+n8n-cat-bot[bot]@users.noreply.github.com> Date: Wed, 21 Oct 2026 11:45:17 +0000 Subject: [PATCH] fix: Handle null and undefined in manual console output (#41570) Co-authored-by: n8n-cat-bot[bot] --- .../__tests__/execute-context.test.ts | 40 +++++++++++++++++++ .../base-execute-context.ts | 2 + 2 files changed, 42 insertions(+) diff --git a/packages/core/src/execution-engine/node-execution-context/__tests__/execute-context.test.ts b/packages/core/src/execution-engine/node-execution-context/__tests__/execute-context.test.ts index 254ec8d94d1..c489964f17e 100644 --- a/packages/core/src/execution-engine/node-execution-context/__tests__/execute-context.test.ts +++ b/packages/core/src/execution-engine/node-execution-context/__tests__/execute-context.test.ts @@ -254,6 +254,46 @@ describe('ExecuteContext', () => { }); describe('logNodeOutput', () => { + // NODE-5746: Forward valid Code node logs to the editor without server warnings. + it.each([ + { logCall: 'console.log("x", 42)', args: ['x', 42], messages: ['x', 42] }, + { logCall: 'console.log(null)', args: [null], messages: ['null'] }, + { logCall: 'console.log(undefined)', args: [undefined], messages: ['undefined'] }, + { logCall: 'console.log("x", null)', args: ['x', null], messages: ['x', 'null'] }, + ])( + 'should forward $logCall to the editor in manual mode without warnings', + ({ args, messages }) => { + const sendDataToUI = vi.fn(); + const codeNode = mock({ + name: 'Code', + type: 'n8n-nodes-base.code', + typeVersion: 2, + }); + const context = new ExecuteContext( + mock({ settings: { redactionPolicy: 'none' } }), + codeNode, + mock({ sendDataToUI }), + 'manual', + mock(), + runIndex, + connectionInputData, + inputData, + executeData, + [], + ); + const warnSpy = vi.spyOn(context.logger, 'warn').mockImplementation(() => {}); + + context.logNodeOutput(...args); + + expect.soft(warnSpy).not.toHaveBeenCalled(); + expect(sendDataToUI).toHaveBeenCalledTimes(1); + expect(sendDataToUI).toHaveBeenCalledWith('sendConsoleMessage', { + source: '[Node: "Code"]', + messages, + }); + }, + ); + it('when in manual mode, should parse JSON', () => { const json = '{"key": "value", "nested": {"foo": "bar"}}'; const expectedParsedObject = { key: 'value', nested: { foo: 'bar' } }; diff --git a/packages/core/src/execution-engine/node-execution-context/base-execute-context.ts b/packages/core/src/execution-engine/node-execution-context/base-execute-context.ts index f15a4b31238..12ddc885797 100644 --- a/packages/core/src/execution-engine/node-execution-context/base-execute-context.ts +++ b/packages/core/src/execution-engine/node-execution-context/base-execute-context.ts @@ -425,6 +425,8 @@ export class BaseExecuteContext extends NodeExecutionContext { try { if (this.additionalData.sendDataToUI) { args = args.map((arg) => { + if (arg === null || arg === undefined) return String(arg); + // prevent invalid dates from being logged as null // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-return if (arg.isLuxonDateTime && arg.invalidReason) return { ...arg };