From 8d7b068545a906503a4e6d92884b534ec01135ea Mon Sep 17 00:00:00 2001 From: "sentry[bot]" <39604003+sentry[bot]@users.noreply.github.com> Date: Sat, 12 Sep 2026 10:42:19 +0000 Subject: [PATCH 1/2] fix(uptime): Prevent Environment.DoesNotExist on monitor update --- src/sentry/uptime/endpoints/validators.py | 14 +++++++------ .../test_project_uptime_alert_details.py | 20 +++++++++++++++++++ 2 files changed, 28 insertions(+), 6 deletions(-) diff --git a/src/sentry/uptime/endpoints/validators.py b/src/sentry/uptime/endpoints/validators.py index 8c619a85da74..f925a78bcf8b 100644 --- a/src/sentry/uptime/endpoints/validators.py +++ b/src/sentry/uptime/endpoints/validators.py @@ -417,14 +417,16 @@ def update(self, instance: Detector, data): ) if "environment" in data: + env_name = data["environment"] + else: + env_name = instance.config["environment"] + + if env_name is None: + environment = None + else: environment = Environment.get_or_create( project=self.context["project"], - name=data["environment"], - ) - else: - environment = Environment.objects.get( - projects=self.context["project"], - name=instance.config["environment"], + name=env_name, ) if "mode" in data: diff --git a/tests/sentry/uptime/endpoints/test_project_uptime_alert_details.py b/tests/sentry/uptime/endpoints/test_project_uptime_alert_details.py index d8d5b5ae36f0..f254784d9dab 100644 --- a/tests/sentry/uptime/endpoints/test_project_uptime_alert_details.py +++ b/tests/sentry/uptime/endpoints/test_project_uptime_alert_details.py @@ -125,6 +125,26 @@ def test_enviroment(self) -> None: assert detector.name == "test" assert detector.config.get("environment") == "uptime-prod" + def test_update_without_environment_when_monitor_has_none(self) -> None: + """Regression test: updating a monitor created without an environment + must not raise Environment.DoesNotExist when environment is omitted from + the PUT payload.""" + detector = self.create_uptime_detector() + # Confirm the monitor has no environment set + assert detector.config.get("environment") is None + + resp = self.get_success_response( + self.organization.slug, + detector.linked_project.slug, + detector.id, + name="updated-name", + ) + detector.refresh_from_db() + assert resp.data == serialize(detector, self.user, UptimeDetectorSerializer()) + assert detector.name == "updated-name" + # Environment should remain None + assert detector.config.get("environment") is None + def test_user(self) -> None: detector = self.create_uptime_detector() From 612ed00dccde1aaa6cb264775bc1549e25f8acac Mon Sep 17 00:00:00 2001 From: "sentry[bot]" <39604003+sentry[bot]@users.noreply.github.com> Date: Sat, 12 Sep 2026 11:02:01 +0000 Subject: [PATCH 2/2] fix(uptime): Prevent Environment.DoesNotExist on monitor update --- .../uptime/endpoints/test_project_uptime_alert_details.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/sentry/uptime/endpoints/test_project_uptime_alert_details.py b/tests/sentry/uptime/endpoints/test_project_uptime_alert_details.py index f254784d9dab..0b7d1147ad2f 100644 --- a/tests/sentry/uptime/endpoints/test_project_uptime_alert_details.py +++ b/tests/sentry/uptime/endpoints/test_project_uptime_alert_details.py @@ -130,7 +130,10 @@ def test_update_without_environment_when_monitor_has_none(self) -> None: must not raise Environment.DoesNotExist when environment is omitted from the PUT payload.""" detector = self.create_uptime_detector() - # Confirm the monitor has no environment set + # Simulate a monitor that was created without an environment by clearing + # the environment from the config (mirrors the pre-existing bug scenario). + detector.config["environment"] = None + detector.save(update_fields=["config"]) assert detector.config.get("environment") is None resp = self.get_success_response(