From 77f884f5d4c220bd78a7ad22d8e58b1e1d4a041b Mon Sep 17 00:00:00 2001 From: Sonarly Claude Code Date: Tue, 21 Apr 2026 10:31:47 +0000 Subject: [PATCH] Fix unguarded JSON.parse on email body in tool-executor-workflow-action https://sonarly.com/issue/29388?type=bug Workflow SEND_EMAIL and DRAFT_EMAIL actions crash with a SyntaxError when the email body is not valid JSON, due to a missing try/catch around JSON.parse introduced in the v2.0.1 release. Fix: Wrapped the `JSON.parse(resolvedBody!)` and `renderRichTextToHtml()` calls in a try/catch block in `tool-executor-workflow-action.ts`. When the email body is not valid JSON (e.g., HTML from the new email composer, plain text from legacy workflows, or bodies with unresolved template variables), the catch block falls back to using the resolved body string as-is. This restores the graceful error handling that was present in the deleted `parseEmailBody` utility, which had an identical try/catch pattern: ```ts try { return JSON.parse(body); } catch { return body; } ``` The fallback is safe because `email-composer.service.ts` (the downstream consumer) now expects HTML input and sanitizes it with DOMPurify before sending. --- .../tool-executor-workflow-action.ts | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/packages/twenty-server/src/modules/workflow/workflow-executor/workflow-actions/tool-executor-workflow-action.ts b/packages/twenty-server/src/modules/workflow/workflow-executor/workflow-actions/tool-executor-workflow-action.ts index b096ddc5e4e..c25f6d2285e 100644 --- a/packages/twenty-server/src/modules/workflow/workflow-executor/workflow-actions/tool-executor-workflow-action.ts +++ b/packages/twenty-server/src/modules/workflow/workflow-executor/workflow-actions/tool-executor-workflow-action.ts @@ -69,8 +69,17 @@ export class ToolExecutorWorkflowAction implements WorkflowAction { if (emailInput.body) { const resolvedBody = resolveRichTextVariables(emailInput.body, context); - const bodyJson = JSON.parse(resolvedBody!); - const htmlBody = await renderRichTextToHtml(bodyJson); + + let htmlBody: string; + + try { + const bodyJson = JSON.parse(resolvedBody!); + + htmlBody = await renderRichTextToHtml(bodyJson); + } catch { + // Body is not valid JSON (e.g. HTML, plain text, or unresolved variables) + htmlBody = resolvedBody!; + } toolInput = { ...emailInput,