Skip to content

fix(iswf): Updates the display label for alerts to use Workflow by default, when available#112887

Open
GabeVillalobos wants to merge 1 commit intomasterfrom
gv/fix_issue_alert_rule_labels
Open

fix(iswf): Updates the display label for alerts to use Workflow by default, when available#112887
GabeVillalobos wants to merge 1 commit intomasterfrom
gv/fix_issue_alert_rule_labels

Conversation

@GabeVillalobos
Copy link
Copy Markdown
Member

Currently, we display a mixture of Detector name and alert rule link in issue alert footers. This is confusing from a user perspective, so this PR attempts to use the workflow name when available.

@github-actions github-actions bot added the Scope: Backend Automatically applied to PRs that change backend components label Apr 13, 2026
@GabeVillalobos GabeVillalobos marked this pull request as ready for review April 13, 2026 23:48
@GabeVillalobos GabeVillalobos requested review from a team as code owners April 13, 2026 23:48
Copy link
Copy Markdown
Contributor

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

Bugbot Autofix prepared a fix for the issue found in the latest run.

  • ✅ Fixed: Unnecessary DB query for test notification workflow ID
    • Added a guard to skip Workflow.objects.get when workflow_id is TEST_NOTIFICATION_ID, preventing the guaranteed-failing test-notification lookup.

Create PR

Or push these changes by commenting:

@cursor push 4ea2161e1d
Preview (4ea2161e1d)
diff --git a/src/sentry/notifications/notification_action/types.py b/src/sentry/notifications/notification_action/types.py
--- a/src/sentry/notifications/notification_action/types.py
+++ b/src/sentry/notifications/notification_action/types.py
@@ -202,7 +202,7 @@
         rule_id = None
 
         label = None
-        if workflow_id is not None:
+        if workflow_id is not None and workflow_id != TEST_NOTIFICATION_ID:
             try:
                 workflow = Workflow.objects.get(id=workflow_id)
                 label = workflow.name

This Bugbot Autofix run was free. To enable autofix for future PRs, go to the Cursor dashboard.

Reviewed by Cursor Bugbot for commit b859389. Configure here.

except Workflow.DoesNotExist:
# If the workflow no longer exists, bail and use detector name
# as a fallback.
pass
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unnecessary DB query for test notification workflow ID

Low Severity

When workflow_id equals TEST_NOTIFICATION_ID (-1), the new code at lines 205–212 queries Workflow.objects.get(id=-1) before the test-notification check at line 220. This query will always raise Workflow.DoesNotExist for the sentinel value -1, resulting in a wasted database round-trip on every test notification. Previously, label was set directly to detector.name without any DB query. The guard for TEST_NOTIFICATION_ID needs to happen before the Workflow lookup.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit b859389. Configure here.

Comment on lines +205 to +215
if workflow_id is not None:
try:
workflow = Workflow.objects.get(id=workflow_id)
label = workflow.name
except Workflow.DoesNotExist:
# If the workflow no longer exists, bail and use detector name
# as a fallback.
pass

if label is None:
label = detector.name
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: The new logic setting the alert label to workflow.name is immediately overwritten by existing code that uses the legacy rule's label for migrated alerts.
Severity: HIGH

Suggested Fix

Refactor the logic to ensure the workflow.name is prioritized. The code block that fetches and applies the legacy rule label from AlertRuleWorkflow should only execute if the label has not already been set by the new workflow logic. This will ensure the new workflow name is used when available, as intended.

Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent.
Verify if this is a real issue. If it is, propose a fix; if not, explain why it's not
valid.

Location: src/sentry/notifications/notification_action/types.py#L204-L215

Potential issue: The new code sets the alert `label` to the `workflow.name` when a
workflow is available. However, for migrated alerts, a subsequent block of existing code
checks for an `AlertRuleWorkflow` record. If this record is found, it overwrites the
`label` with the label from the legacy `Rule`. This negates the intended change for the
primary use case of migrated alerts, causing the old rule label to be displayed instead
of the new workflow name. The issue is masked by insufficient test coverage.

Did we get this right? 👍 / 👎 to inform future reviews.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That should be dead code at this point. We shouldn't have a case where that ID is None at this current phase of the deployment.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 13, 2026

Backend Test Failures

Failures on f52975d in this run:

tests/sentry/notifications/platform/slack/renderers/test_issue.py::IssueSlackRendererTest::test_render_with_noteslog
[gw0] linux -- Python 3.13.1 /home/runner/work/sentry/sentry/.venv/bin/python3
tests/sentry/notifications/platform/slack/renderers/test_issue.py:308: in test_render_with_notes
    assert result == self._build_expected_blocks(
E   assert {'blocks': [{...] test event'} == {'blocks': [{...] test event'}
E     
E     Omitting 1 identical items, use -vv to show
E     Differing items:
E     {'blocks': [{'block_id': '{"issue":59,"rule":135}', 'text': {'text': ':red_circle: <http://testserver/organizations/ba...erver/organizations/baz/monitors/alerts/135/|Optimal Owl>    Short ID: BAR-1', 'type': 'mrkdwn'}], 'type': 'context'}]} != {'blocks': [{'block_id': '{"issue":59,"rule":135}', 'text': {'text': ':red_circle: <http://testserver/organizations/ba...ver/organizations/baz/monitors/alerts/135/|Test Detector>    Short ID: BAR-1', 'type': 'mrkdwn'}], 'type': 'context'}]}
E     
E     Full diff:
E       {
E           'blocks': [
E               {
E                   'block_id': '{"issue":59,"rule":135}',
E                   'text': {
E                       'text': ':red_circle: '
E                       '<http://testserver/organizations/baz/issues/59/events/d47fbc22c12749248e36395491aa3ef2/?referrer=slack&workflow_id=135&alert_type=issue|*test '
E                       'event*>',
E                       'type': 'mrkdwn',
E                   },
E                   'type': 'section',
E               },
E               {
E                   'elements': [
E                       {
E                           'text': 'State: *New*   First Seen: *Just now*',
E                           'type': 'mrkdwn',
E                       },
E                   ],
E                   'type': 'context',
E               },
E               {
E                   'elements': [
E                       {
E                           'action_id': 'status::4557963448942608::4557963448942608',
E                           'text': {
E                               'text': 'Resolve',
E                               'type': 'plain_text',
E                           },
E                           'type': 'button',
E                           'value': 'resolved',
E                       },
E                       {
E                           'action_id': 'archive_dialog::4557963448942608::4557963448942608',
E                           'text': {
E                               'text': 'Archive',
E                               'type': 'plain_text',
E                           },
E                           'type': 'button',
E                           'value': 'archive_dialog',
... (42 more lines)
tests/sentry/notifications/platform/slack/renderers/test_issue.py::IssueNotificationDataTest::test_from_action_invocationlog
[gw0] linux -- Python 3.13.1 /home/runner/work/sentry/sentry/.venv/bin/python3
tests/sentry/notifications/platform/slack/renderers/test_issue.py:102: in test_from_action_invocation
    assert result.rule.label == invocation.detector.name
E   AssertionError: assert 'Touching Grub' == 'Test Detector'
E     
E     - Test Detector
E     + Touching Grub
tests/sentry/notifications/platform/slack/renderers/test_issue.py::IssueSlackRendererTest::test_render_produces_blockslog
[gw0] linux -- Python 3.13.1 /home/runner/work/sentry/sentry/.venv/bin/python3
tests/sentry/notifications/platform/slack/renderers/test_issue.py:287: in test_render_produces_blocks
    assert result == self._build_expected_blocks(
E   assert {'blocks': [{...] test event'} == {'blocks': [{...] test event'}
E     
E     Omitting 1 identical items, use -vv to show
E     Differing items:
E     {'blocks': [{'block_id': '{"issue":44,"rule":123}', 'text': {'text': ':red_circle: <http://testserver/organizations/ba...r/organizations/baz/monitors/alerts/123/|Tender Mosquito>    Short ID: BAR-1', 'type': 'mrkdwn'}], 'type': 'context'}]} != {'blocks': [{'block_id': '{"issue":44,"rule":123}', 'text': {'text': ':red_circle: <http://testserver/organizations/ba...ver/organizations/baz/monitors/alerts/123/|Test Detector>    Short ID: BAR-1', 'type': 'mrkdwn'}], 'type': 'context'}]}
E     
E     Full diff:
E       {
E           'blocks': [
E               {
E                   'block_id': '{"issue":44,"rule":123}',
E                   'text': {
E                       'text': ':red_circle: '
E                       '<http://testserver/organizations/baz/issues/44/events/9382ad7798844bc6adad247beb86c22f/?referrer=slack&workflow_id=123&alert_type=issue|*test '
E                       'event*>',
E                       'type': 'mrkdwn',
E                   },
E                   'type': 'section',
E               },
E               {
E                   'elements': [
E                       {
E                           'text': 'State: *New*   First Seen: *Just now*',
E                           'type': 'mrkdwn',
E                       },
E                   ],
E                   'type': 'context',
E               },
E               {
E                   'elements': [
E                       {
E                           'action_id': 'status::4557963448549392::4557963448549392',
E                           'text': {
E                               'text': 'Resolve',
E                               'type': 'plain_text',
E                           },
E                           'type': 'button',
E                           'value': 'resolved',
E                       },
E                       {
E                           'action_id': 'archive_dialog::4557963448549392::4557963448549392',
E                           'text': {
E                               'text': 'Archive',
E                               'type': 'plain_text',
E                           },
E                           'type': 'button',
E                           'value': 'archive_dialog',
... (35 more lines)
tests/sentry/notifications/platform/slack/renderers/test_issue.py::IssueSlackRendererTest::test_render_with_tagslog
[gw0] linux -- Python 3.13.1 /home/runner/work/sentry/sentry/.venv/bin/python3
tests/sentry/notifications/platform/slack/renderers/test_issue.py:333: in test_render_with_tags
    assert result == self._build_expected_blocks(
E   assert {'blocks': [{...tagged event'} == {'blocks': [{...tagged event'}
E     
E     Omitting 1 identical items, use -vv to show
E     Differing items:
E     {'blocks': [{'block_id': '{"issue":50,"rule":129}', 'text': {'text': ':red_circle: <http://testserver/organizations/ba...erver/organizations/baz/monitors/alerts/129/|Bold Roughy>    Short ID: BAR-1', 'type': 'mrkdwn'}], 'type': 'context'}]} != {'blocks': [{'block_id': '{"issue":50,"rule":129}', 'text': {'text': ':red_circle: <http://testserver/organizations/ba...ver/organizations/baz/monitors/alerts/129/|Test Detector>    Short ID: BAR-1', 'type': 'mrkdwn'}], 'type': 'context'}]}
E     
E     Full diff:
E       {
E           'blocks': [
E               {
E                   'block_id': '{"issue":50,"rule":129}',
E                   'text': {
E                       'text': ':red_circle: '
E                       '<http://testserver/organizations/baz/issues/50/events/fbdd6033b19f436e98c22c1abbafdacc/?referrer=slack&workflow_id=129&alert_type=issue|*tagged '
E                       'event*>',
E                       'type': 'mrkdwn',
E                   },
E                   'type': 'section',
E               },
E               {
E                   'block_id': '{"issue":50,"rule":129,"block":"tags"}',
E                   'text': {
E                       'text': 'level: `error`  ',
E                       'type': 'mrkdwn',
E                   },
E                   'type': 'section',
E               },
E               {
E                   'elements': [
E                       {
E                           'text': 'State: *New*   First Seen: *Just now*',
E                           'type': 'mrkdwn',
E                       },
E                   ],
E                   'type': 'context',
E               },
E               {
E                   'elements': [
E                       {
E                           'action_id': 'status::4557963448942608::4557963448942608',
E                           'text': {
E                               'text': 'Resolve',
E                               'type': 'plain_text',
E                           },
E                           'type': 'button',
E                           'value': 'resolved',
E                       },
... (43 more lines)
tests/sentry/rules/actions/test_notify_event_service.py::NotifyEventServiceWebhookActionTest::test_applies_correctly_for_legacy_webhooks_acilog
[gw0] linux -- Python 3.13.1 /home/runner/work/sentry/sentry/.venv/bin/python3
tests/sentry/rules/actions/test_notify_event_service.py:139: in test_applies_correctly_for_legacy_webhooks_aci
    assert payload["triggering_rules"] == ["error_detector"]
E   AssertionError: assert ['error_workflow'] == ['error_detector']
E     
E     At index 0 diff: 'error_workflow' != 'error_detector'
E     
E     Full diff:
E       [
E     -     'error_detector',
E     +     'error_workflow',
E       ]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Scope: Backend Automatically applied to PRs that change backend components

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant