From 6ce23a4115deb1efe4b2f96d36bfb66c55cb907b Mon Sep 17 00:00:00 2001 From: Sonarly Claude Code Date: Wed, 15 Apr 2026 19:49:42 +0000 Subject: [PATCH] fix(twenty-front): return null instead of throwing in SeeVersionWorkflowRunSingleRecordCommand MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit https://sonarly.com/issue/26767?type=bug The "See Version" command menu button on the workflowRuns index page throws an unhandled error when the selected record's `workflowVersion` relation data isn't loaded in the record store, causing a snackbar error and Sentry noise. Fix: Two changes were made: 1. ROOT CAUSE FIX (SeeVersionWorkflowRunSingleRecordCommand.tsx): Changed `throw new Error('Selected record is required to see version workflow run')` to `return null`. Why: On the /objects/workflowRuns index page, record index queries use shallow depth and don't load nested relation objects like `workflowVersion: { id: ... }`. When a user selects a workflowRun row, this pinned command mounts immediately via CommandRunner and tries to access `selectedRecord.workflowVersion.id`, which is undefined. The throw crashes the component, triggers the error boundary, shows an error snackbar, and fires a Sentry event. Returning null instead is the correct pattern — the sibling SeeWorkflowWorkflowRunSingleRecordCommand handles the same scenario with `return null`. The error boundary renders a null fallback anyway, so the throw provides no benefit over returning null directly. The command simply becomes a no-op when relation data isn't available. 2. MONITORING IMPROVEMENT (CommandMenuItemErrorBoundary.tsx): Enhanced the Sentry capture to: - Add `commandMenuItemId` tag for easier filtering/debugging - Set severity level to `warning` instead of default `error` — command menu errors are recoverable (the boundary renders null), not fatal - Add fingerprint `['command-menu-item-error', error.message]` so Sentry groups events by message rather than creating duplicate issues per stack trace variation This reduces Sentry noise from expected edge cases that reach the error boundary. --- .../display/components/CommandMenuItemErrorBoundary.tsx | 6 ++++++ .../components/SeeVersionWorkflowRunSingleRecordCommand.tsx | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/packages/twenty-front/src/modules/command-menu-item/display/components/CommandMenuItemErrorBoundary.tsx b/packages/twenty-front/src/modules/command-menu-item/display/components/CommandMenuItemErrorBoundary.tsx index 4ba8ff34de1..1d6dfcb252a 100644 --- a/packages/twenty-front/src/modules/command-menu-item/display/components/CommandMenuItemErrorBoundary.tsx +++ b/packages/twenty-front/src/modules/command-menu-item/display/components/CommandMenuItemErrorBoundary.tsx @@ -29,6 +29,12 @@ export const CommandMenuItemErrorBoundary = ({ const { captureException } = await import('@sentry/react'); captureException(error, (scope) => { scope.setTag('component', 'CommandMenuItem'); + scope.setTag('commandMenuItemId', commandMenuItemId); + scope.setLevel('warning'); + scope.setFingerprint([ + 'command-menu-item-error', + error.message, + ]); return scope; }); diff --git a/packages/twenty-front/src/modules/command-menu-item/engine-command/record/single-record/workflow-runs/components/SeeVersionWorkflowRunSingleRecordCommand.tsx b/packages/twenty-front/src/modules/command-menu-item/engine-command/record/single-record/workflow-runs/components/SeeVersionWorkflowRunSingleRecordCommand.tsx index 52bde380d96..981af422b4d 100644 --- a/packages/twenty-front/src/modules/command-menu-item/engine-command/record/single-record/workflow-runs/components/SeeVersionWorkflowRunSingleRecordCommand.tsx +++ b/packages/twenty-front/src/modules/command-menu-item/engine-command/record/single-record/workflow-runs/components/SeeVersionWorkflowRunSingleRecordCommand.tsx @@ -11,7 +11,7 @@ export const SeeVersionWorkflowRunSingleRecordCommand = () => { !isDefined(selectedRecord) || !isDefined(selectedRecord?.workflowVersion?.id) ) { - throw new Error('Selected record is required to see version workflow run'); + return null; } return (