diff --git a/packages/cli/src/runners/__tests__/task-runner-ws-server.test.ts b/packages/cli/src/runners/__tests__/task-runner-ws-server.test.ts index b092e08fed..24b12fa190 100644 --- a/packages/cli/src/runners/__tests__/task-runner-ws-server.test.ts +++ b/packages/cli/src/runners/__tests__/task-runner-ws-server.test.ts @@ -58,4 +58,28 @@ describe('TaskRunnerWsServer', () => { expect(clearIntervalSpy).toHaveBeenCalled(); }); }); + + describe('sendMessage', () => { + it('should work with a message containing circular references', () => { + const server = new TaskRunnerWsServer(mock(), mock(), mock(), mock(), mock()); + const ws = mock(); + server.runnerConnections.set('test-runner', ws); + + const messageData: Record = {}; + messageData.circular = messageData; + + expect(() => + server.sendMessage('test-runner', { + type: 'broker:taskdataresponse', + taskId: 'taskId', + requestId: 'requestId', + data: messageData, + }), + ).not.toThrow(); + + expect(ws.send).toHaveBeenCalledWith( + '{"type":"broker:taskdataresponse","taskId":"taskId","requestId":"requestId","data":{"circular":"[Circular Reference]"}}', + ); + }); + }); }); diff --git a/packages/cli/src/runners/runner-ws-server.ts b/packages/cli/src/runners/runner-ws-server.ts index 3a5fa53029..8ea3a7edbe 100644 --- a/packages/cli/src/runners/runner-ws-server.ts +++ b/packages/cli/src/runners/runner-ws-server.ts @@ -1,6 +1,6 @@ import { TaskRunnersConfig } from '@n8n/config'; import type { BrokerMessage, RunnerMessage } from '@n8n/task-runner'; -import { ApplicationError } from 'n8n-workflow'; +import { ApplicationError, jsonStringify } from 'n8n-workflow'; import { Service } from 'typedi'; import type WebSocket from 'ws'; @@ -83,7 +83,7 @@ export class TaskRunnerWsServer { } sendMessage(id: TaskRunner['id'], message: BrokerMessage.ToRunner.All) { - this.runnerConnections.get(id)?.send(JSON.stringify(message)); + this.runnerConnections.get(id)?.send(jsonStringify(message, { replaceCircularRefs: true })); } add(id: TaskRunner['id'], connection: WebSocket) {