Skip to content

feat(workflows): Restrict APIs based on metrics alert features#112600

Open
kcons wants to merge 4 commits intomasterfrom
kcons/checkit
Open

feat(workflows): Restrict APIs based on metrics alert features#112600
kcons wants to merge 4 commits intomasterfrom
kcons/checkit

Conversation

@kcons
Copy link
Copy Markdown
Member

@kcons kcons commented Apr 9, 2026

Fixes ISWF-2401.

@github-actions github-actions bot added the Scope: Backend Automatically applied to PRs that change backend components label Apr 9, 2026
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 9, 2026

Backend Test Failures

Failures on 11282d7 in this run:

tests/sentry/incidents/endpoints/validators/test_validators.py::TestMetricAlertsCreateDetectorValidator::test_create_with_valid_datalog
[gw0] linux -- Python 3.13.1 /home/runner/work/sentry/sentry/.venv/bin/python3
tests/sentry/incidents/endpoints/validators/test_validators.py:293: in test_create_with_valid_data
    detector = self.create_static_detector()
tests/sentry/incidents/endpoints/validators/test_validators.py:203: in create_static_detector
    assert validator.is_valid(), validator.errors
E   AssertionError: {'nonFieldErrors': [ErrorDetail(string='Your organization does not have access to the events dataset for metric alert subscriptions.', code='invalid')]}
E   assert False
E    +  where False = <bound method BaseSerializer.is_valid of MetricIssueDetectorValidator(context={'organization': <Organization at 0x7f55...quired=False)\n    enabled = BooleanField(help_text='Set to False if you want to disable the monitor.', required=False)>()
E    +    where <bound method BaseSerializer.is_valid of MetricIssueDetectorValidator(context={'organization': <Organization at 0x7f55...quired=False)\n    enabled = BooleanField(help_text='Set to False if you want to disable the monitor.', required=False)> = MetricIssueDetectorValidator(context={'organization': <Organization at 0x7f55f707cd70: id=4557939477053456, owner_id=N...equired=False)\n    enabled = BooleanField(help_text='Set to False if you want to disable the monitor.', required=False).is_valid
tests/sentry/incidents/endpoints/validators/test_validators.py::TestMetricAlertsCreateDetectorValidator::test_enforce_quota_calls_loglog
[gw0] linux -- Python 3.13.1 /home/runner/work/sentry/sentry/.venv/bin/python3
tests/sentry/incidents/endpoints/validators/test_validators.py:536: in test_enforce_quota_calls_log
    validator.save()
.venv/lib/python3.13/site-packages/rest_framework/serializers.py:182: in save
    assert not self.errors, (
E   AssertionError: You cannot call `.save()` on a serializer with invalid data.
tests/sentry/incidents/endpoints/validators/test_validators.py::TestMetricAlertsCreateDetectorValidator::test_enforce_quota_feature_disabledlog
[gw0] linux -- Python 3.13.1 /home/runner/work/sentry/sentry/.venv/bin/python3
tests/sentry/incidents/endpoints/validators/test_validators.py:486: in test_enforce_quota_feature_disabled
    assert validator.is_valid()
E   AssertionError: assert False
E    +  where False = <bound method BaseSerializer.is_valid of MetricIssueDetectorValidator(context={'organization': <Organization at 0x7f55...quired=False)\n    enabled = BooleanField(help_text='Set to False if you want to disable the monitor.', required=False)>()
E    +    where <bound method BaseSerializer.is_valid of MetricIssueDetectorValidator(context={'organization': <Organization at 0x7f55...quired=False)\n    enabled = BooleanField(help_text='Set to False if you want to disable the monitor.', required=False)> = MetricIssueDetectorValidator(context={'organization': <Organization at 0x7f55f7aa8a50: id=4557939477643280, owner_id=N...equired=False)\n    enabled = BooleanField(help_text='Set to False if you want to disable the monitor.', required=False).is_valid
tests/sentry/incidents/endpoints/validators/test_validators.py::TestMetricAlertsCreateDetectorValidator::test_transaction_dataset_deprecation_multiple_data_sourceslog
[gw0] linux -- Python 3.13.1 /home/runner/work/sentry/sentry/.venv/bin/python3
tests/sentry/incidents/endpoints/validators/test_validators.py:605: in test_transaction_dataset_deprecation_multiple_data_sources
    assert validator.is_valid(), validator.errors
E   AssertionError: {'nonFieldErrors': [ErrorDetail(string='Your organization does not have access to the transactions dataset for metric alert subscriptions.', code='invalid')]}
E   assert False
E    +  where False = <bound method BaseSerializer.is_valid of MetricIssueDetectorValidator(context={'organization': <Organization at 0x7f55...quired=False)\n    enabled = BooleanField(help_text='Set to False if you want to disable the monitor.', required=False)>()
E    +    where <bound method BaseSerializer.is_valid of MetricIssueDetectorValidator(context={'organization': <Organization at 0x7f55...quired=False)\n    enabled = BooleanField(help_text='Set to False if you want to disable the monitor.', required=False)> = MetricIssueDetectorValidator(context={'organization': <Organization at 0x7f55f7169f90: id=4557939477905424, owner_id=N...equired=False)\n    enabled = BooleanField(help_text='Set to False if you want to disable the monitor.', required=False).is_valid
tests/sentry/incidents/endpoints/validators/test_validators.py::TestMetricAlertsCreateDetectorValidator::test_transaction_dataset_deprecation_transactionslog
[gw0] linux -- Python 3.13.1 /home/runner/work/sentry/sentry/.venv/bin/python3
tests/sentry/incidents/endpoints/validators/test_validators.py:556: in test_transaction_dataset_deprecation_transactions
    assert validator.is_valid(), validator.errors
E   AssertionError: {'nonFieldErrors': [ErrorDetail(string='Your organization does not have access to the transactions dataset for metric alert subscriptions.', code='invalid')]}
E   assert False
E    +  where False = <bound method BaseSerializer.is_valid of MetricIssueDetectorValidator(context={'organization': <Organization at 0x7f55...quired=False)\n    enabled = BooleanField(help_text='Set to False if you want to disable the monitor.', required=False)>()
E    +    where <bound method BaseSerializer.is_valid of MetricIssueDetectorValidator(context={'organization': <Organization at 0x7f55...quired=False)\n    enabled = BooleanField(help_text='Set to False if you want to disable the monitor.', required=False)> = MetricIssueDetectorValidator(context={'organization': <Organization at 0x7f55f71bec10: id=4557939478102032, owner_id=N...equired=False)\n    enabled = BooleanField(help_text='Set to False if you want to disable the monitor.', required=False).is_valid
tests/sentry/incidents/endpoints/validators/test_validators.py::TestMetricAlertsUpdateDetectorValidator::test_transaction_dataset_deprecation_generic_metrics_updatelog
[gw0] linux -- Python 3.13.1 /home/runner/work/sentry/sentry/.venv/bin/python3
tests/sentry/incidents/endpoints/validators/test_validators.py:1405: in test_transaction_dataset_deprecation_generic_metrics_update
    assert validator.is_valid(), validator.errors
E   AssertionError: {'nonFieldErrors': [ErrorDetail(string='Your organization does not have access to the generic_metrics dataset for metric alert subscriptions.', code='invalid')]}
E   assert False
E    +  where False = <bound method BaseSerializer.is_valid of MetricIssueDetectorValidator(context={'organization': <Organization at 0x7f55...quired=False)\n    enabled = BooleanField(help_text='Set to False if you want to disable the monitor.', required=False)>()
E    +    where <bound method BaseSerializer.is_valid of MetricIssueDetectorValidator(context={'organization': <Organization at 0x7f55...quired=False)\n    enabled = BooleanField(help_text='Set to False if you want to disable the monitor.', required=False)> = MetricIssueDetectorValidator(context={'organization': <Organization at 0x7f55f707caf0: id=4557939478429712, owner_id=N...equired=False)\n    enabled = BooleanField(help_text='Set to False if you want to disable the monitor.', required=False).is_valid
tests/sentry/incidents/endpoints/validators/test_validators.py::TestMetricAlertsUpdateDetectorValidator::test_update_anomaly_detection_event_typeslog
[gw0] linux -- Python 3.13.1 /home/runner/work/sentry/sentry/.venv/bin/python3
tests/sentry/incidents/endpoints/validators/test_validators.py:1247: in test_update_anomaly_detection_event_types
    detector = self.create_dynamic_detector()
tests/sentry/incidents/endpoints/validators/test_validators.py:233: in create_dynamic_detector
    assert validator.is_valid(), validator.errors
E   AssertionError: {'nonFieldErrors': [ErrorDetail(string='Your organization does not have access to the events dataset for metric alert subscriptions.', code='invalid')]}
E   assert False
E    +  where False = <bound method BaseSerializer.is_valid of MetricIssueDetectorValidator(context={'organization': <Organization at 0x7f55...quired=False)\n    enabled = BooleanField(help_text='Set to False if you want to disable the monitor.', required=False)>()
E    +    where <bound method BaseSerializer.is_valid of MetricIssueDetectorValidator(context={'organization': <Organization at 0x7f55...quired=False)\n    enabled = BooleanField(help_text='Set to False if you want to disable the monitor.', required=False)> = MetricIssueDetectorValidator(context={'organization': <Organization at 0x7f55f7fb4050: id=4557939478691856, owner_id=N...equired=False)\n    enabled = BooleanField(help_text='Set to False if you want to disable the monitor.', required=False).is_valid
tests/sentry/incidents/endpoints/validators/test_validators.py::TestMetricAlertsUpdateDetectorValidator::test_update_anomaly_detection_snuba_query_aggregatelog
[gw0] linux -- Python 3.13.1 /home/runner/work/sentry/sentry/.venv/bin/python3
tests/sentry/incidents/endpoints/validators/test_validators.py:1048: in test_update_anomaly_detection_snuba_query_aggregate
    detector = self.create_dynamic_detector()
tests/sentry/incidents/endpoints/validators/test_validators.py:233: in create_dynamic_detector
    assert validator.is_valid(), validator.errors
E   AssertionError: {'nonFieldErrors': [ErrorDetail(string='Your organization does not have access to the events dataset for metric alert subscriptions.', code='invalid')]}
E   assert False
E    +  where False = <bound method BaseSerializer.is_valid of MetricIssueDetectorValidator(context={'organization': <Organization at 0x7f55...quired=False)\n    enabled = BooleanField(help_text='Set to False if you want to disable the monitor.', required=False)>()
E    +    where <bound method BaseSerializer.is_valid of MetricIssueDetectorValidator(context={'organization': <Organization at 0x7f55...quired=False)\n    enabled = BooleanField(help_text='Set to False if you want to disable the monitor.', required=False)> = MetricIssueDetectorValidator(context={'organization': <Organization at 0x7f55f7a619f0: id=4557939478888464, owner_id=N...equired=False)\n    enabled = BooleanField(help_text='Set to False if you want to disable the monitor.', required=False).is_valid
tests/sentry/incidents/endpoints/validators/test_validators.py::TestMetricAlertsUpdateDetectorValidator::test_update_anomaly_detection_snuba_query_querylog
[gw0] linux -- Python 3.13.1 /home/runner/work/sentry/sentry/.venv/bin/python3
tests/sentry/incidents/endpoints/validators/test_validators.py:980: in test_update_anomaly_detection_snuba_query_query
    detector = self.create_dynamic_detector()
tests/sentry/incidents/endpoints/validators/test_validators.py:233: in create_dynamic_detector
    assert validator.is_valid(), validator.errors
E   AssertionError: {'nonFieldErrors': [ErrorDetail(string='Your organization does not have access to the events dataset for metric alert subscriptions.', code='invalid')]}
E   assert False
E    +  where False = <bound method BaseSerializer.is_valid of MetricIssueDetectorValidator(context={'organization': <Organization at 0x7f55...quired=False)\n    enabled = BooleanField(help_text='Set to False if you want to disable the monitor.', required=False)>()
E    +    where <bound method BaseSerializer.is_valid of MetricIssueDetectorValidator(context={'organization': <Organization at 0x7f55...quired=False)\n    enabled = BooleanField(help_text='Set to False if you want to disable the monitor.', required=False)> = MetricIssueDetectorValidator(context={'organization': <Organization at 0x7f55f59a8f50: id=4557939479150608, owner_id=N...equired=False)\n    enabled = BooleanField(help_text='Set to False if you want to disable the monitor.', required=False).is_valid
tests/sentry/incidents/endpoints/validators/test_validators.py::TestMetricAlertsUpdateDetectorValidator::test_update_anomaly_detection_snuba_query_to_perflog
[gw0] linux -- Python 3.13.1 /home/runner/work/sentry/sentry/.venv/bin/python3
tests/sentry/incidents/endpoints/validators/test_validators.py:1189: in test_update_anomaly_detection_snuba_query_to_perf
    detector = self.create_dynamic_detector()
tests/sentry/incidents/endpoints/validators/test_validators.py:233: in create_dynamic_detector
    assert validator.is_valid(), validator.errors
E   AssertionError: {'nonFieldErrors': [ErrorDetail(string='Your organization does not have access to the events dataset for metric alert subscriptions.', code='invalid')]}
E   assert False
E    +  where False = <bound method BaseSerializer.is_valid of MetricIssueDetectorValidator(context={'organization': <Organization at 0x7f55...quired=False)\n    enabled = BooleanField(help_text='Set to False if you want to disable the monitor.', required=False)>()
E    +    where <bound method BaseSerializer.is_valid of MetricIssueDetectorValidator(context={'organization': <Organization at 0x7f55...quired=False)\n    enabled = BooleanField(help_text='Set to False if you want to disable the monitor.', required=False)> = MetricIssueDetectorValidator(context={'organization': <Organization at 0x7f55f7b68870: id=4557939479347216, owner_id=N...equired=False)\n    enabled = BooleanField(help_text='Set to False if you want to disable the monitor.', required=False).is_valid
tests/sentry/incidents/endpoints/validators/test_validators.py::TestMetricAlertsUpdateDetectorValidator::test_update_data_source_marks_query_as_user_updated_when_snapshot_existslog
[gw0] linux -- Python 3.13.1 /home/runner/work/sentry/sentry/.venv/bin/python3
tests/sentry/incidents/endpoints/validators/test_validators.py:791: in test_update_data_source_marks_query_as_user_updated_when_snapshot_exists
    detector = self.create_static_detector()
tests/sentry/incidents/endpoints/validators/test_validators.py:203: in create_static_detector
    assert validator.is_valid(), validator.errors
E   AssertionError: {'nonFieldErrors': [ErrorDetail(string='Your organization does not have access to the events dataset for metric alert subscriptions.', code='invalid')]}
E   assert False
E    +  where False = <bound method BaseSerializer.is_valid of MetricIssueDetectorValidator(context={'organization': <Organization at 0x7f56...quired=False)\n    enabled = BooleanField(help_text='Set to False if you want to disable the monitor.', required=False)>()
E    +    where <bound method BaseSerializer.is_valid of MetricIssueDetectorValidator(context={'organization': <Organization at 0x7f56...quired=False)\n    enabled = BooleanField(help_text='Set to False if you want to disable the monitor.', required=False)> = MetricIssueDetectorValidator(context={'organization': <Organization at 0x7f5609bb9270: id=4557939479609360, owner_id=N...equired=False)\n    enabled = BooleanField(help_text='Set to False if you want to disable the monitor.', required=False).is_valid
tests/sentry/workflow_engine/endpoints/test_organization_detector_details.py::OrganizationDetectorDetailsGetTest::test_simplelog
[gw1] linux -- Python 3.13.1 /home/runner/work/sentry/sentry/.venv/bin/python3
tests/sentry/workflow_engine/endpoints/test_organization_detector_details.py:117: in test_simple
    response = self.get_success_response(self.organization.slug, self.detector.id)
src/sentry/testutils/cases.py:631: in get_success_response
    assert_status_code(response, status.HTTP_200_OK)
src/sentry/testutils/asserts.py:46: in assert_status_code
    assert minimum <= response.status_code < maximum, response
E   AssertionError: <Response status_code=500, "application/json">
E   assert 500 < 201
E    +  where 500 = <Response status_code=500, "application/json">.status_code
tests/sentry/workflow_engine/endpoints/test_organization_detector_details.py::OrganizationDetectorDetailsPutTest::test_updatelog
[gw1] linux -- Python 3.13.1 /home/runner/work/sentry/sentry/.venv/bin/python3
tests/sentry/workflow_engine/endpoints/test_organization_detector_details.py:310: in test_update
    response = self.get_success_response(
src/sentry/testutils/cases.py:629: in get_success_response
    assert_status_code(response, status_code)
src/sentry/testutils/asserts.py:46: in assert_status_code
    assert minimum <= response.status_code < maximum, response
E   AssertionError: <Response status_code=500, "application/json">
E   assert 500 < 201
E    +  where 500 = <Response status_code=500, "application/json">.status_code
tests/sentry/workflow_engine/endpoints/test_organization_detector_details.py::OrganizationDetectorDetailsPutTest::test_update_config_invalid_schemalog
[gw1] linux -- Python 3.13.1 /home/runner/work/sentry/sentry/.venv/bin/python3
tests/sentry/workflow_engine/endpoints/test_organization_detector_details.py:902: in test_update_config_invalid_schema
    response = self.get_error_response(
src/sentry/testutils/cases.py:663: in get_error_response
    assert_status_code(response, status_code)
src/sentry/testutils/asserts.py:46: in assert_status_code
    assert minimum <= response.status_code < maximum, response
E   AssertionError: <Response status_code=500, "application/json">
E   assert 500 < 401
E    +  where 500 = <Response status_code=500, "application/json">.status_code
tests/sentry/workflow_engine/endpoints/test_organization_detector_details.py::OrganizationDetectorDetailsPutTest::test_update_descriptionlog
[gw1] linux -- Python 3.13.1 /home/runner/work/sentry/sentry/.venv/bin/python3
tests/sentry/workflow_engine/endpoints/test_organization_detector_details.py:346: in test_update_description
    self.get_success_response(
src/sentry/testutils/cases.py:629: in get_success_response
    assert_status_code(response, status_code)
src/sentry/testutils/asserts.py:46: in assert_status_code
    assert minimum <= response.status_code < maximum, response
E   AssertionError: <Response status_code=500, "application/json">
E   assert 500 < 201
E    +  where 500 = <Response status_code=500, "application/json">.status_code
tests/sentry/workflow_engine/endpoints/test_organization_detector_details.py::OrganizationDetectorDetailsPutTest::test_update_eap_invalid_time_window_rejectedlog
[gw1] linux -- Python 3.13.1 /home/runner/work/sentry/sentry/.venv/bin/python3
tests/sentry/workflow_engine/endpoints/test_organization_detector_details.py:369: in test_update_eap_invalid_time_window_rejected
    response = self.get_error_response(
src/sentry/testutils/cases.py:663: in get_error_response
    assert_status_code(response, status_code)
src/sentry/testutils/asserts.py:46: in assert_status_code
    assert minimum <= response.status_code < maximum, response
E   AssertionError: <Response status_code=500, "application/json">
E   assert 500 < 401
E    +  where 500 = <Response status_code=500, "application/json">.status_code
tests/sentry/workflow_engine/endpoints/test_organization_detector_details.py::OrganizationDetectorDetailsPutTest::test_update_owner_to_userlog
[gw1] linux -- Python 3.13.1 /home/runner/work/sentry/sentry/.venv/bin/python3
tests/sentry/workflow_engine/endpoints/test_organization_detector_details.py:469: in test_update_owner_to_user
    response = self.get_success_response(
src/sentry/testutils/cases.py:629: in get_success_response
    assert_status_code(response, status_code)
src/sentry/testutils/asserts.py:46: in assert_status_code
    assert minimum <= response.status_code < maximum, response
E   AssertionError: <Response status_code=500, "application/json">
E   assert 500 < 201
E    +  where 500 = <Response status_code=500, "application/json">.status_code
tests/sentry/workflow_engine/endpoints/test_organization_detector_details.py::OrganizationDetectorDetailsPutTest::test_update_workflows_invalid_workflow_idslog
[gw1] linux -- Python 3.13.1 /home/runner/work/sentry/sentry/.venv/bin/python3
tests/sentry/workflow_engine/endpoints/test_organization_detector_details.py:724: in test_update_workflows_invalid_workflow_ids
    response = self.get_error_response(
src/sentry/testutils/cases.py:663: in get_error_response
    assert_status_code(response, status_code)
src/sentry/testutils/asserts.py:46: in assert_status_code
    assert minimum <= response.status_code < maximum, response
E   AssertionError: <Response status_code=500, "application/json">
E   assert 500 < 401
E    +  where 500 = <Response status_code=500, "application/json">.status_code
tests/sentry/workflow_engine/endpoints/test_organization_detector_details.py::OrganizationDetectorDetailsPutCacheInvalidationTest::test_put_invalidates_cachelog
[gw1] linux -- Python 3.13.1 /home/runner/work/sentry/sentry/.venv/bin/python3
tests/sentry/workflow_engine/endpoints/test_organization_detector_details.py:1201: in test_put_invalidates_cache
    self.get_success_response(
src/sentry/testutils/cases.py:629: in get_success_response
    assert_status_code(response, status_code)
src/sentry/testutils/asserts.py:46: in assert_status_code
    assert minimum <= response.status_code < maximum, response
E   AssertionError: <Response status_code=500, "application/json">
E   assert 500 < 201
E    +  where 500 = <Response status_code=500, "application/json">.status_code
tests/sentry/incidents/endpoints/validators/test_validators.py::TestMetricAlertsCreateDetectorValidator::test_anomaly_detectionlog
[gw1] linux -- Python 3.13.1 /home/runner/work/sentry/sentry/.venv/bin/python3
tests/sentry/incidents/endpoints/validators/test_validators.py:313: in test_anomaly_detection
    detector = self.create_dynamic_detector()
tests/sentry/incidents/endpoints/validators/test_validators.py:233: in create_dynamic_detector
    assert validator.is_valid(), validator.errors
E   AssertionError: {'nonFieldErrors': [ErrorDetail(string='Your organization does not have access to the events dataset for metric alert subscriptions.', code='invalid')]}
E   assert False
E    +  where False = <bound method BaseSerializer.is_valid of MetricIssueDetectorValidator(context={'organization': <Organization at 0x7f22...quired=False)\n    enabled = BooleanField(help_text='Set to False if you want to disable the monitor.', required=False)>()
E    +    where <bound method BaseSerializer.is_valid of MetricIssueDetectorValidator(context={'organization': <Organization at 0x7f22...quired=False)\n    enabled = BooleanField(help_text='Set to False if you want to disable the monitor.', required=False)> = MetricIssueDetectorValidator(context={'organization': <Organization at 0x7f2295088910: id=4557939478233120, owner_id=N...equired=False)\n    enabled = BooleanField(help_text='Set to False if you want to disable the monitor.', required=False).is_valid
tests/sentry/incidents/endpoints/validators/test_validators.py::TestMetricAlertsCreateDetectorValidator::test_transaction_dataset_deprecation_generic_metricslog
[gw1] linux -- Python 3.13.1 /home/runner/work/sentry/sentry/.venv/bin/python3
tests/sentry/incidents/endpoints/validators/test_validators.py:580: in test_transaction_dataset_deprecation_generic_metrics
    assert validator.is_valid(), validator.errors
E   AssertionError: {'nonFieldErrors': [ErrorDetail(string='Your organization does not have access to the generic_metrics dataset for metric alert subscriptions.', code='invalid')]}
E   assert False
E    +  where False = <bound method BaseSerializer.is_valid of MetricIssueDetectorValidator(context={'organization': <Organization at 0x7f22...quired=False)\n    enabled = BooleanField(help_text='Set to False if you want to disable the monitor.', required=False)>()
E    +    where <bound method BaseSerializer.is_valid of MetricIssueDetectorValidator(context={'organization': <Organization at 0x7f22...quired=False)\n    enabled = BooleanField(help_text='Set to False if you want to disable the monitor.', required=False)> = MetricIssueDetectorValidator(context={'organization': <Organization at 0x7f2294751770: id=4557939478495264, owner_id=N...equired=False)\n    enabled = BooleanField(help_text='Set to False if you want to disable the monitor.', required=False).is_valid
tests/sentry/incidents/endpoints/validators/test_validators.py::TestMetricAlertsUpdateDetectorValidator::test_invalid_extrapolation_mode_updatelog
[gw1] linux -- Python 3.13.1 /home/runner/work/sentry/sentry/.venv/bin/python3
tests/sentry/incidents/endpoints/validators/test_validators.py:1522: in test_invalid_extrapolation_mode_update
    assert validator.is_valid(), validator.errors
E   AssertionError: {'nonFieldErrors': [ErrorDetail(string='Your organization does not have access to the events_analytics_platform dataset for metric alert subscriptions.', code='invalid')]}
E   assert False
E    +  where False = <bound method BaseSerializer.is_valid of MetricIssueDetectorValidator(context={'organization': <Organization at 0x7f22...quired=False)\n    enabled = BooleanField(help_text='Set to False if you want to disable the monitor.', required=False)>()
E    +    where <bound method BaseSerializer.is_valid of MetricIssueDetectorValidator(context={'organization': <Organization at 0x7f22...quired=False)\n    enabled = BooleanField(help_text='Set to False if you want to disable the monitor.', required=False)> = MetricIssueDetectorValidator(context={'organization': <Organization at 0x7f2295292350: id=4557939478822944, owner_id=N...equired=False)\n    enabled = BooleanField(help_text='Set to False if you want to disable the monitor.', required=False).is_valid
tests/sentry/incidents/endpoints/validators/test_validators.py::TestMetricAlertsUpdateDetectorValidator::test_transaction_dataset_deprecation_update_to_transactionslog
[gw1] linux -- Python 3.13.1 /home/runner/work/sentry/sentry/.venv/bin/python3
tests/sentry/incidents/endpoints/validators/test_validators.py:1450: in test_transaction_dataset_deprecation_update_to_transactions
    assert validator.is_valid(), validator.errors
E   AssertionError: {'nonFieldErrors': [ErrorDetail(string='Your organization does not have access to the events_analytics_platform dataset for metric alert subscriptions.', code='invalid')]}
E   assert False
E    +  where False = <bound method BaseSerializer.is_valid of MetricIssueDetectorValidator(context={'organization': <Organization at 0x7f22...quired=False)\n    enabled = BooleanField(help_text='Set to False if you want to disable the monitor.', required=False)>()
E    +    where <bound method BaseSerializer.is_valid of MetricIssueDetectorValidator(context={'organization': <Organization at 0x7f22...quired=False)\n    enabled = BooleanField(help_text='Set to False if you want to disable the monitor.', required=False)> = MetricIssueDetectorValidator(context={'organization': <Organization at 0x7f229493bbb0: id=4557939479085088, owner_id=N...equired=False)\n    enabled = BooleanField(help_text='Set to False if you want to disable the monitor.', required=False).is_valid
tests/sentry/incidents/endpoints/validators/test_validators.py::TestMetricAlertsUpdateDetectorValidator::test_update_allowed_even_with_deprecated_datasetlog
[gw1] linux -- Python 3.13.1 /home/runner/work/sentry/sentry/.venv/bin/python3
tests/sentry/incidents/endpoints/validators/test_validators.py:1375: in test_update_allowed_even_with_deprecated_dataset
    assert validator.is_valid(), validator.errors
E   AssertionError: {'nonFieldErrors': [ErrorDetail(string='Your organization does not have access to the events dataset for metric alert subscriptions.', code='invalid')]}
E   assert False
E    +  where False = <bound method BaseSerializer.is_valid of MetricIssueDetectorValidator(context={'organization': <Organization at 0x7f22...quired=False)\n    enabled = BooleanField(help_text='Set to False if you want to disable the monitor.', required=False)>()
E    +    where <bound method BaseSerializer.is_valid of MetricIssueDetectorValidator(context={'organization': <Organization at 0x7f22...quired=False)\n    enabled = BooleanField(help_text='Set to False if you want to disable the monitor.', required=False)> = MetricIssueDetectorValidator(context={'organization': <Organization at 0x7f229493bc50: id=4557939479347232, owner_id=N...equired=False)\n    enabled = BooleanField(help_text='Set to False if you want to disable the monitor.', required=False).is_valid
tests/sentry/incidents/endpoints/validators/test_validators.py::TestMetricAlertsUpdateDetectorValidator::test_update_anomaly_detection_no_configlog
[gw1] linux -- Python 3.13.1 /home/runner/work/sentry/sentry/.venv/bin/python3
tests/sentry/incidents/endpoints/validators/test_validators.py:1119: in test_update_anomaly_detection_no_config
    detector = self.create_dynamic_detector()
tests/sentry/incidents/endpoints/validators/test_validators.py:233: in create_dynamic_detector
    assert validator.is_valid(), validator.errors
E   AssertionError: {'nonFieldErrors': [ErrorDetail(string='Your organization does not have access to the events dataset for metric alert subscriptions.', code='invalid')]}
E   assert False
E    +  where False = <bound method BaseSerializer.is_valid of MetricIssueDetectorValidator(context={'organization': <Organization at 0x7f22...quired=False)\n    enabled = BooleanField(help_text='Set to False if you want to disable the monitor.', required=False)>()
E    +    where <bound method BaseSerializer.is_valid of MetricIssueDetectorValidator(context={'organization': <Organization at 0x7f22...quired=False)\n    enabled = BooleanField(help_text='Set to False if you want to disable the monitor.', required=False)> = MetricIssueDetectorValidator(context={'organization': <Organization at 0x7f22a0dd8870: id=4557939479543840, owner_id=N...equired=False)\n    enabled = BooleanField(help_text='Set to False if you want to disable the monitor.', required=False).is_valid
tests/sentry/incidents/endpoints/validators/test_validators.py::TestMetricAlertsUpdateDetectorValidator::test_update_with_valid_datalog
[gw1] linux -- Python 3.13.1 /home/runner/work/sentry/sentry/.venv/bin/python3
tests/sentry/incidents/endpoints/validators/test_validators.py:755: in test_update_with_valid_data
    detector = self.create_static_detector()
tests/sentry/incidents/endpoints/validators/test_validators.py:203: in create_static_detector
    assert validator.is_valid(), validator.errors
E   AssertionError: {'nonFieldErrors': [ErrorDetail(string='Your organization does not have access to the events dataset for metric alert subscriptions.', code='invalid')]}
E   assert False
E    +  where False = <bound method BaseSerializer.is_valid of MetricIssueDetectorValidator(context={'organization': <Organization at 0x7f22...quired=False)\n    enabled = BooleanField(help_text='Set to False if you want to disable the monitor.', required=False)>()
E    +    where <bound method BaseSerializer.is_valid of MetricIssueDetectorValidator(context={'organization': <Organization at 0x7f22...quired=False)\n    enabled = BooleanField(help_text='Set to False if you want to disable the monitor.', required=False)> = MetricIssueDetectorValidator(context={'organization': <Organization at 0x7f2295a5fe30: id=4557939479805984, owner_id=N...equired=False)\n    enabled = BooleanField(help_text='Set to False if you want to disable the monitor.', required=False).is_valid
tests/sentry/workflow_engine/endpoints/test_organization_detector_details.py::OrganizationDetectorDetailsGetTest::test_metric_detector_not_allowed_returns_404log
[gw0] linux -- Python 3.13.1 /home/runner/work/sentry/sentry/.venv/bin/python3
tests/sentry/workflow_engine/endpoints/test_organization_detector_details.py:236: in test_metric_detector_not_allowed_returns_404
    self.get_error_response(self.organization.slug, self.detector.id, status_code=404)
src/sentry/testutils/cases.py:663: in get_error_response
    assert_status_code(response, status_code)
src/sentry/testutils/asserts.py:46: in assert_status_code
    assert minimum <= response.status_code < maximum, response
E   AssertionError: <Response status_code=500, "application/json">
E   assert 500 < 405
E    +  where 500 = <Response status_code=500, "application/json">.status_code
tests/sentry/workflow_engine/endpoints/test_organization_detector_details.py::OrganizationDetectorDetailsGetTest::test_permission_allowed_when_open_membership_enabledlog
[gw0] linux -- Python 3.13.1 /home/runner/work/sentry/sentry/.venv/bin/python3
tests/sentry/workflow_engine/endpoints/test_organization_detector_details.py:158: in test_permission_allowed_when_open_membership_enabled
    response = self.get_success_response(self.organization.slug, self.detector.id)
src/sentry/testutils/cases.py:631: in get_success_response
    assert_status_code(response, status.HTTP_200_OK)
src/sentry/testutils/asserts.py:46: in assert_status_code
    assert minimum <= response.status_code < maximum, response
E   AssertionError: <Response status_code=500, "application/json">
E   assert 500 < 201
E    +  where 500 = <Response status_code=500, "application/json">.status_code
tests/sentry/workflow_engine/endpoints/test_organization_detector_details.py::OrganizationDetectorDetailsGetTest::test_permission_allowed_when_user_has_team_membershiplog
[gw0] linux -- Python 3.13.1 /home/runner/work/sentry/sentry/.venv/bin/python3
tests/sentry/workflow_engine/endpoints/test_organization_detector_details.py:181: in test_permission_allowed_when_user_has_team_membership
    response = self.get_success_response(self.organization.slug, self.detector.id)
src/sentry/testutils/cases.py:631: in get_success_response
    assert_status_code(response, status.HTTP_200_OK)
src/sentry/testutils/asserts.py:46: in assert_status_code
    assert minimum <= response.status_code < maximum, response
E   AssertionError: <Response status_code=500, "application/json">
E   assert 500 < 201
E    +  where 500 = <Response status_code=500, "application/json">.status_code
tests/sentry/workflow_engine/endpoints/test_organization_detector_details.py::OrganizationDetectorDetailsGetTest::test_with_alert_rule_mappinglog
[gw0] linux -- Python 3.13.1 /home/runner/work/sentry/sentry/.venv/bin/python3
tests/sentry/workflow_engine/endpoints/test_organization_detector_details.py:204: in test_with_alert_rule_mapping
    response = self.get_success_response(self.organization.slug, self.detector.id)
src/sentry/testutils/cases.py:631: in get_success_response
    assert_status_code(response, status.HTTP_200_OK)
src/sentry/testutils/asserts.py:46: in assert_status_code
    assert minimum <= response.status_code < maximum, response
E   AssertionError: <Response status_code=500, "application/json">
E   assert 500 < 201
E    +  where 500 = <Response status_code=500, "application/json">.status_code
tests/sentry/workflow_engine/endpoints/test_organization_detector_details.py::OrganizationDetectorDetailsGetTest::test_without_alert_rule_mappinglog
[gw0] linux -- Python 3.13.1 /home/runner/work/sentry/sentry/.venv/bin/python3
tests/sentry/workflow_engine/endpoints/test_organization_detector_details.py:221: in test_without_alert_rule_mapping
    response = self.get_success_response(self.organization.slug, self.detector.id)
src/sentry/testutils/cases.py:631: in get_success_response
    assert_status_code(response, status.HTTP_200_OK)
src/sentry/testutils/asserts.py:46: in assert_status_code
    assert minimum <= response.status_code < maximum, response
E   AssertionError: <Response status_code=500, "application/json">
E   assert 500 < 201
E    +  where 500 = <Response status_code=500, "application/json">.status_code
tests/sentry/workflow_engine/endpoints/test_organization_detector_details.py::OrganizationDetectorDetailsPutTest::test_enable_detectorlog
[gw0] linux -- Python 3.13.1 /home/runner/work/sentry/sentry/.venv/bin/python3
tests/sentry/workflow_engine/endpoints/test_organization_detector_details.py:581: in test_enable_detector
    response = self.get_success_response(
src/sentry/testutils/cases.py:629: in get_success_response
    assert_status_code(response, status_code)
src/sentry/testutils/asserts.py:46: in assert_status_code
    assert minimum <= response.status_code < maximum, response
E   AssertionError: <Response status_code=500, "application/json">
E   assert 500 < 201
E    +  where 500 = <Response status_code=500, "application/json">.status_code
tests/sentry/workflow_engine/endpoints/test_organization_detector_details.py::OrganizationDetectorDetailsPutTest::test_update_add_data_conditionlog
[gw0] linux -- Python 3.13.1 /home/runner/work/sentry/sentry/.venv/bin/python3
tests/sentry/workflow_engine/endpoints/test_organization_detector_details.py:426: in test_update_add_data_condition
    response = self.get_success_response(
src/sentry/testutils/cases.py:629: in get_success_response
    assert_status_code(response, status_code)
src/sentry/testutils/asserts.py:46: in assert_status_code
    assert minimum <= response.status_code < maximum, response
E   AssertionError: <Response status_code=500, "application/json">
E   assert 500 < 201
E    +  where 500 = <Response status_code=500, "application/json">.status_code
tests/sentry/workflow_engine/endpoints/test_organization_detector_details.py::OrganizationDetectorDetailsPutTest::test_update_config_validlog
[gw0] linux -- Python 3.13.1 /home/runner/work/sentry/sentry/.venv/bin/python3
tests/sentry/workflow_engine/endpoints/test_organization_detector_details.py:877: in test_update_config_valid
    response = self.get_success_response(
src/sentry/testutils/cases.py:629: in get_success_response
    assert_status_code(response, status_code)
src/sentry/testutils/asserts.py:46: in assert_status_code
    assert minimum <= response.status_code < maximum, response
E   AssertionError: <Response status_code=500, "application/json">
E   assert 500 < 201
E    +  where 500 = <Response status_code=500, "application/json">.status_code
tests/sentry/workflow_engine/endpoints/test_organization_detector_details.py::OrganizationDetectorDetailsPutTest::test_update_data_source_marks_user_updated_when_snapshot_existslog
[gw0] linux -- Python 3.13.1 /home/runner/work/sentry/sentry/.venv/bin/python3
tests/sentry/workflow_engine/endpoints/test_organization_detector_details.py:1041: in test_update_data_source_marks_user_updated_when_snapshot_exists
    self.get_success_response(
src/sentry/testutils/cases.py:629: in get_success_response
    assert_status_code(response, status_code)
src/sentry/testutils/asserts.py:46: in assert_status_code
    assert minimum <= response.status_code < maximum, response
E   AssertionError: <Response status_code=500, "application/json">
E   assert 500 < 201
E    +  where 500 = <Response status_code=500, "application/json">.status_code
tests/sentry/workflow_engine/endpoints/test_organization_detector_details.py::OrganizationDetectorDetailsPutTest::test_update_workflows_replace_workflowslog
[gw0] linux -- Python 3.13.1 /home/runner/work/sentry/sentry/.venv/bin/python3
tests/sentry/workflow_engine/endpoints/test_organization_detector_details.py:643: in test_update_workflows_replace_workflows
    response = self.get_success_response(
src/sentry/testutils/cases.py:629: in get_success_response
    assert_status_code(response, status_code)
src/sentry/testutils/asserts.py:46: in assert_status_code
    assert minimum <= response.status_code < maximum, response
E   AssertionError: <Response status_code=500, "application/json">
E   assert 500 < 201
E    +  where 500 = <Response status_code=500, "application/json">.status_code
tests/sentry/incidents/endpoints/validators/test_validators.py::TestMetricAlertsCreateDetectorValidator::test_anomaly_detection__send_historical_data_failslog
[gw1] linux -- Python 3.13.1 /home/runner/work/sentry/sentry/.venv/bin/python3
tests/sentry/incidents/endpoints/validators/test_validators.py:378: in test_anomaly_detection__send_historical_data_fails
    assert validator.is_valid(), validator.errors
E   AssertionError: {'nonFieldErrors': [ErrorDetail(string='Your organization does not have access to the events dataset for metric alert subscriptions.', code='invalid')]}
E   assert False
E    +  where False = <bound method BaseSerializer.is_valid of MetricIssueDetectorValidator(context={'organization': <Organization at 0x7f34...quired=False)\n    enabled = BooleanField(help_text='Set to False if you want to disable the monitor.', required=False)>()
E    +    where <bound method BaseSerializer.is_valid of MetricIssueDetectorValidator(context={'organization': <Organization at 0x7f34...quired=False)\n    enabled = BooleanField(help_text='Set to False if you want to disable the monitor.', required=False)> = MetricIssueDetectorValidator(context={'organization': <Organization at 0x7f34003396d0: id=4557939477250080, owner_id=N...equired=False)\n    enabled = BooleanField(help_text='Set to False if you want to disable the monitor.', required=False).is_valid
tests/sentry/incidents/endpoints/validators/test_validators.py::TestMetricAlertsCreateDetectorValidator::test_enforce_quota_within_limitlog
[gw1] linux -- Python 3.13.1 /home/runner/work/sentry/sentry/.venv/bin/python3
tests/sentry/incidents/endpoints/validators/test_validators.py:514: in test_enforce_quota_within_limit
    assert validator.is_valid()
E   AssertionError: assert False
E    +  where False = <bound method BaseSerializer.is_valid of MetricIssueDetectorValidator(context={'organization': <Organization at 0x7f34...quired=False)\n    enabled = BooleanField(help_text='Set to False if you want to disable the monitor.', required=False)>()
E    +    where <bound method BaseSerializer.is_valid of MetricIssueDetectorValidator(context={'organization': <Organization at 0x7f34...quired=False)\n    enabled = BooleanField(help_text='Set to False if you want to disable the monitor.', required=False)> = MetricIssueDetectorValidator(context={'organization': <Organization at 0x7f3400d77a70: id=4557939477577760, owner_id=N...equired=False)\n    enabled = BooleanField(help_text='Set to False if you want to disable the monitor.', required=False).is_valid
tests/sentry/incidents/endpoints/validators/test_validators.py::TestMetricAlertsTraceMetricsValidator::test_create_detector_trace_metrics_valid_aggregateslog
[gw1] linux -- Python 3.13.1 /home/runner/work/sentry/sentry/.venv/bin/python3
tests/sentry/incidents/endpoints/validators/test_validators.py:712: in test_create_detector_trace_metrics_valid_aggregates
    assert validator_per_second.is_valid(), validator_per_second.errors
E   AssertionError: {'nonFieldErrors': [ErrorDetail(string='Your organization does not have access to the events_analytics_platform dataset for metric alert subscriptions.', code='invalid')]}
E   assert False
E    +  where False = <bound method BaseSerializer.is_valid of MetricIssueDetectorValidator(context={'organization': <Organization at 0x7f33...quired=False)\n    enabled = BooleanField(help_text='Set to False if you want to disable the monitor.', required=False)>()
E    +    where <bound method BaseSerializer.is_valid of MetricIssueDetectorValidator(context={'organization': <Organization at 0x7f33...quired=False)\n    enabled = BooleanField(help_text='Set to False if you want to disable the monitor.', required=False)> = MetricIssueDetectorValidator(context={'organization': <Organization at 0x7f33f6bab890: id=4557939477970976, owner_id=N...equired=False)\n    enabled = BooleanField(help_text='Set to False if you want to disable the monitor.', required=False).is_valid
tests/sentry/incidents/endpoints/validators/test_validators.py::TestMetricAlertsUpdateDetectorValidator::test_anomaly_detection__send_historical_data_snuba_update_failslog
[gw1] linux -- Python 3.13.1 /home/runner/work/sentry/sentry/.venv/bin/python3
tests/sentry/incidents/endpoints/validators/test_validators.py:1336: in test_anomaly_detection__send_historical_data_snuba_update_fails
    detector = self.create_dynamic_detector()
tests/sentry/incidents/endpoints/validators/test_validators.py:233: in create_dynamic_detector
    assert validator.is_valid(), validator.errors
E   AssertionError: {'nonFieldErrors': [ErrorDetail(string='Your organization does not have access to the events dataset for metric alert subscriptions.', code='invalid')]}
E   assert False
E    +  where False = <bound method BaseSerializer.is_valid of MetricIssueDetectorValidator(context={'organization': <Organization at 0x7f33...quired=False)\n    enabled = BooleanField(help_text='Set to False if you want to disable the monitor.', required=False)>()
E    +    where <bound method BaseSerializer.is_valid of MetricIssueDetectorValidator(context={'organization': <Organization at 0x7f33...quired=False)\n    enabled = BooleanField(help_text='Set to False if you want to disable the monitor.', required=False)> = MetricIssueDetectorValidator(context={'organization': <Organization at 0x7f33f6a1edf0: id=4557939478233120, owner_id=N...equired=False)\n    enabled = BooleanField(help_text='Set to False if you want to disable the monitor.', required=False).is_valid
tests/sentry/incidents/endpoints/validators/test_validators.py::TestMetricAlertsUpdateDetectorValidator::test_anomaly_detection__send_historical_data_update_failslog
[gw1] linux -- Python 3.13.1 /home/runner/work/sentry/sentry/.venv/bin/python3
tests/sentry/incidents/endpoints/validators/test_validators.py:1295: in test_anomaly_detection__send_historical_data_update_fails
    static_detector = self.create_static_detector()
tests/sentry/incidents/endpoints/validators/test_validators.py:203: in create_static_detector
    assert validator.is_valid(), validator.errors
E   AssertionError: {'nonFieldErrors': [ErrorDetail(string='Your organization does not have access to the events dataset for metric alert subscriptions.', code='invalid')]}
E   assert False
E    +  where False = <bound method BaseSerializer.is_valid of MetricIssueDetectorValidator(context={'organization': <Organization at 0x7f33...quired=False)\n    enabled = BooleanField(help_text='Set to False if you want to disable the monitor.', required=False)>()
E    +    where <bound method BaseSerializer.is_valid of MetricIssueDetectorValidator(context={'organization': <Organization at 0x7f33...quired=False)\n    enabled = BooleanField(help_text='Set to False if you want to disable the monitor.', required=False)> = MetricIssueDetectorValidator(context={'organization': <Organization at 0x7f33f66a1db0: id=4557939478429728, owner_id=N...equired=False)\n    enabled = BooleanField(help_text='Set to False if you want to disable the monitor.', required=False).is_valid
tests/sentry/incidents/endpoints/validators/test_validators.py::TestMetricAlertsUpdateDetectorValidator::test_nonexistent_extrapolation_mode_updatelog
[gw1] linux -- Python 3.13.1 /home/runner/work/sentry/sentry/.venv/bin/python3
tests/sentry/incidents/endpoints/validators/test_validators.py:1592: in test_nonexistent_extrapolation_mode_update
    assert validator.is_valid(), validator.errors
E   AssertionError: {'nonFieldErrors': [ErrorDetail(string='Your organization does not have access to the events_analytics_platform dataset for metric alert subscriptions.', code='invalid')]}
E   assert False
E    +  where False = <bound method BaseSerializer.is_valid of MetricIssueDetectorValidator(context={'organization': <Organization at 0x7f33...quired=False)\n    enabled = BooleanField(help_text='Set to False if you want to disable the monitor.', required=False)>()
E    +    where <bound method BaseSerializer.is_valid of MetricIssueDetectorValidator(context={'organization': <Organization at 0x7f33...quired=False)\n    enabled = BooleanField(help_text='Set to False if you want to disable the monitor.', required=False)> = MetricIssueDetectorValidator(context={'organization': <Organization at 0x7f33f6898690: id=4557939478626336, owner_id=N...equired=False)\n    enabled = BooleanField(help_text='Set to False if you want to disable the monitor.', required=False).is_valid
tests/sentry/incidents/endpoints/validators/test_validators.py::TestMetricAlertsUpdateDetectorValidator::test_update_anomaly_detection_from_staticlog
[gw1] linux -- Python 3.13.1 /home/runner/work/sentry/sentry/.venv/bin/python3
tests/sentry/incidents/endpoints/validators/test_validators.py:918: in test_update_anomaly_detection_from_static
    static_detector = self.create_static_detector()
tests/sentry/incidents/endpoints/validators/test_validators.py:203: in create_static_detector
    assert validator.is_valid(), validator.errors
E   AssertionError: {'nonFieldErrors': [ErrorDetail(string='Your organization does not have access to the events dataset for metric alert subscriptions.', code='invalid')]}
E   assert False
E    +  where False = <bound method BaseSerializer.is_valid of MetricIssueDetectorValidator(context={'organization': <Organization at 0x7f33...quired=False)\n    enabled = BooleanField(help_text='Set to False if you want to disable the monitor.', required=False)>()
E    +    where <bound method BaseSerializer.is_valid of MetricIssueDetectorValidator(context={'organization': <Organization at 0x7f33...quired=False)\n    enabled = BooleanField(help_text='Set to False if you want to disable the monitor.', required=False)> = MetricIssueDetectorValidator(context={'organization': <Organization at 0x7f33f62eca50: id=4557939478888480, owner_id=N...equired=False)\n    enabled = BooleanField(help_text='Set to False if you want to disable the monitor.', required=False).is_valid
tests/sentry/incidents/endpoints/validators/test_validators.py::TestMetricAlertsUpdateDetectorValidator::test_update_anomaly_detection_to_staticlog
[gw1] linux -- Python 3.13.1 /home/runner/work/sentry/sentry/.venv/bin/python3
tests/sentry/incidents/endpoints/validators/test_validators.py:891: in test_update_anomaly_detection_to_static
    dynamic_detector = self.create_dynamic_detector()
tests/sentry/incidents/endpoints/validators/test_validators.py:233: in create_dynamic_detector
    assert validator.is_valid(), validator.errors
E   AssertionError: {'nonFieldErrors': [ErrorDetail(string='Your organization does not have access to the events dataset for metric alert subscriptions.', code='invalid')]}
E   assert False
E    +  where False = <bound method BaseSerializer.is_valid of MetricIssueDetectorValidator(context={'organization': <Organization at 0x7f33...quired=False)\n    enabled = BooleanField(help_text='Set to False if you want to disable the monitor.', required=False)>()
E    +    where <bound method BaseSerializer.is_valid of MetricIssueDetectorValidator(context={'organization': <Organization at 0x7f33...quired=False)\n    enabled = BooleanField(help_text='Set to False if you want to disable the monitor.', required=False)> = MetricIssueDetectorValidator(context={'organization': <Organization at 0x7f33f5db9950: id=4557939479085088, owner_id=N...equired=False)\n    enabled = BooleanField(help_text='Set to False if you want to disable the monitor.', required=False).is_valid
tests/sentry/incidents/endpoints/validators/test_validators.py::TestMetricAlertsUpdateDetectorValidator::test_update_data_source_does_not_mark_user_updated_when_no_snapshotlog
[gw1] linux -- Python 3.13.1 /home/runner/work/sentry/sentry/.venv/bin/python3
tests/sentry/incidents/endpoints/validators/test_validators.py:834: in test_update_data_source_does_not_mark_user_updated_when_no_snapshot
    detector = self.create_static_detector()
tests/sentry/incidents/endpoints/validators/test_validators.py:203: in create_static_detector
    assert validator.is_valid(), validator.errors
E   AssertionError: {'nonFieldErrors': [ErrorDetail(string='Your organization does not have access to the events dataset for metric alert subscriptions.', code='invalid')]}
E   assert False
E    +  where False = <bound method BaseSerializer.is_valid of MetricIssueDetectorValidator(context={'organization': <Organization at 0x7f33...quired=False)\n    enabled = BooleanField(help_text='Set to False if you want to disable the monitor.', required=False)>()
E    +    where <bound method BaseSerializer.is_valid of MetricIssueDetectorValidator(context={'organization': <Organization at 0x7f33...quired=False)\n    enabled = BooleanField(help_text='Set to False if you want to disable the monitor.', required=False)> = MetricIssueDetectorValidator(context={'organization': <Organization at 0x7f33f5be8910: id=4557939479281696, owner_id=N...equired=False)\n    enabled = BooleanField(help_text='Set to False if you want to disable the monitor.', required=False).is_valid
tests/sentry/workflow_engine/endpoints/test_organization_detector_details.py::OrganizationDetectorDetailsGetTest::test_with_issue_rule_mappinglog
[gw0] linux -- Python 3.13.1 /home/runner/work/sentry/sentry/.venv/bin/python3
tests/sentry/workflow_engine/endpoints/test_organization_detector_details.py:214: in test_with_issue_rule_mapping
    response = self.get_success_response(self.organization.slug, self.detector.id)
src/sentry/testutils/cases.py:631: in get_success_response
    assert_status_code(response, status.HTTP_200_OK)
src/sentry/testutils/asserts.py:46: in assert_status_code
    assert minimum <= response.status_code < maximum, response
E   AssertionError: <Response status_code=500, "application/json">
E   assert 500 < 201
E    +  where 500 = <Response status_code=500, "application/json">.status_code
tests/sentry/workflow_engine/endpoints/test_organization_detector_details.py::OrganizationDetectorDetailsPutTest::test_anomaly_detection_to_staticlog
[gw0] linux -- Python 3.13.1 /home/runner/work/sentry/sentry/.venv/bin/python3
tests/sentry/workflow_engine/endpoints/test_organization_detector_details.py:993: in test_anomaly_detection_to_static
    response = self.get_success_response(
src/sentry/testutils/cases.py:629: in get_success_response
    assert_status_code(response, status_code)
src/sentry/testutils/asserts.py:46: in assert_status_code
    assert minimum <= response.status_code < maximum, response
E   AssertionError: <Response status_code=500, "application/json">
E   assert 500 < 201
E    +  where 500 = <Response status_code=500, "application/json">.status_code
tests/sentry/workflow_engine/endpoints/test_organization_detector_details.py::OrganizationDetectorDetailsPutTest::test_disable_detectorlog
[gw0] linux -- Python 3.13.1 /home/runner/work/sentry/sentry/.venv/bin/python3
tests/sentry/workflow_engine/endpoints/test_organization_detector_details.py:562: in test_disable_detector
    response = self.get_success_response(
src/sentry/testutils/cases.py:629: in get_success_response
    assert_status_code(response, status_code)
src/sentry/testutils/asserts.py:46: in assert_status_code
    assert minimum <= response.status_code < maximum, response
E   AssertionError: <Response status_code=500, "application/json">
E   assert 500 < 201
E    +  where 500 = <Response status_code=500, "application/json">.status_code
tests/sentry/workflow_engine/endpoints/test_organization_detector_details.py::OrganizationDetectorDetailsPutTest::test_metric_detector_not_allowed_returns_404log
[gw0] linux -- Python 3.13.1 /home/runner/work/sentry/sentry/.venv/bin/python3
tests/sentry/workflow_engine/endpoints/test_organization_detector_details.py:406: in test_metric_detector_not_allowed_returns_404
    self.get_error_response(
src/sentry/testutils/cases.py:663: in get_error_response
    assert_status_code(response, status_code)
src/sentry/testutils/asserts.py:46: in assert_status_code
    assert minimum <= response.status_code < maximum, response
E   AssertionError: <Response status_code=500, "application/json">
E   assert 500 < 405
E    +  where 500 = <Response status_code=500, "application/json">.status_code
tests/sentry/workflow_engine/endpoints/test_organization_detector_details.py::OrganizationDetectorDetailsPutTest::test_update_bad_schemalog
[gw0] linux -- Python 3.13.1 /home/runner/work/sentry/sentry/.venv/bin/python3
tests/sentry/workflow_engine/endpoints/test_organization_detector_details.py:452: in test_update_bad_schema
    self.get_error_response(
src/sentry/testutils/cases.py:663: in get_error_response
    assert_status_code(response, status_code)
src/sentry/testutils/asserts.py:46: in assert_status_code
    assert minimum <= response.status_code < maximum, response
E   AssertionError: <Response status_code=500, "application/json">
E   assert 500 < 401
E    +  where 500 = <Response status_code=500, "application/json">.status_code
tests/sentry/workflow_engine/endpoints/test_organization_detector_details.py::OrganizationDetectorDetailsPutTest::test_update_clear_ownerlog
[gw0] linux -- Python 3.13.1 /home/runner/work/sentry/sentry/.venv/bin/python3
tests/sentry/workflow_engine/endpoints/test_organization_detector_details.py:537: in test_update_clear_owner
    response = self.get_success_response(
src/sent

... (truncated due to GitHub comment size limit)

@linear-code
Copy link
Copy Markdown

linear-code bot commented Apr 10, 2026

@kcons kcons marked this pull request as ready for review April 11, 2026 00:32
@kcons kcons requested review from a team as code owners April 11, 2026 00:32
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 is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit e06e2ae. Configure here.

Comment thread src/sentry/workflow_engine/endpoints/utils/filters.py
Copy link
Copy Markdown
Member

@wedamija wedamija left a comment

Choose a reason for hiding this comment

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

lgtm

Comment on lines +25 to +26
# Cast DataSource.source_id (string) to int so the subquery can use
# the index on QuerySubscription.id.
Copy link
Copy Markdown
Member

@wedamija wedamija Apr 13, 2026

Choose a reason for hiding this comment

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

Is this true? I think the subquery will use the index on project_id and/or snuba_query_id

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.

It is not true. Fixed, but trying to rework this query to be more efficient. Updating coming soon(tm).

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.

3 participants