diff --git a/src/sentry/incidents/endpoints/organization_alert_rule_index.py b/src/sentry/incidents/endpoints/organization_alert_rule_index.py index 91178a4eeed082..866654869b310e 100644 --- a/src/sentry/incidents/endpoints/organization_alert_rule_index.py +++ b/src/sentry/incidents/endpoints/organization_alert_rule_index.py @@ -121,6 +121,13 @@ def create_metric_alert( if not serializer.is_valid(): raise ValidationError(serializer.errors) + # if there are no triggers, then the serializer will raise an error + for trigger in data["triggers"]: + if not trigger.get("actions", []): + raise ValidationError( + "Each trigger must have an associated action for this alert to fire." + ) + trigger_sentry_app_action_creators_for_incidents(serializer.validated_data) if get_slack_actions_with_async_lookups(organization, request.user, request.data): # need to kick off an async job for Slack diff --git a/tests/sentry/incidents/endpoints/test_organization_alert_rule_index.py b/tests/sentry/incidents/endpoints/test_organization_alert_rule_index.py index 1b9a657794ce99..bf124c85aa2204 100644 --- a/tests/sentry/incidents/endpoints/test_organization_alert_rule_index.py +++ b/tests/sentry/incidents/endpoints/test_organization_alert_rule_index.py @@ -921,12 +921,15 @@ def test_critical_trigger_no_action(self): } with self.feature("organizations:incidents"): - resp = self.get_success_response( - self.organization.slug, status_code=201, **rule_one_trigger_only_critical_no_action + resp = self.get_error_response( + self.organization.slug, status_code=400, **rule_one_trigger_only_critical_no_action ) - assert "id" in resp.data - alert_rule = AlertRule.objects.get(id=resp.data["id"]) - assert resp.data == serialize(alert_rule, self.user) + assert resp.data == [ + ErrorDetail( + string="Each trigger must have an associated action for this alert to fire.", + code="invalid", + ) + ] def test_invalid_projects(self): with self.feature("organizations:incidents"): @@ -1009,7 +1012,15 @@ def test_no_owner(self): "name": "JustATestRule", "resolveThreshold": 100, "thresholdType": 1, - "triggers": [{"label": "critical", "alertThreshold": 75}], + "triggers": [ + { + "label": "critical", + "alertThreshold": 75, + "actions": [ + {"type": "email", "targetType": "team", "targetIdentifier": self.team.id} + ], + } + ], } with self.feature("organizations:incidents"):