Skip to content

fix(ACI): Update detector to be monitor for the UI in issue search#114819

Open
saponifi3d wants to merge 1 commit intojcallender/aci/detector-to-monitor-part-2from
jcallender/aci/detector-to-monitor-part-3
Open

fix(ACI): Update detector to be monitor for the UI in issue search#114819
saponifi3d wants to merge 1 commit intojcallender/aci/detector-to-monitor-part-2from
jcallender/aci/detector-to-monitor-part-3

Conversation

@saponifi3d
Copy link
Copy Markdown
Contributor

Description

Last phase of the rename / cleanup; this will remove the legacy references to detector and only support monitor.

  1. Update the BE to support both monitor and detector [PR]
  2. Update the UI [PR]
  3. This PR! 🎉 Cleans up the remnants.

@saponifi3d saponifi3d requested review from a team as code owners May 4, 2026 23:29
@github-actions github-actions Bot added the Scope: Backend Automatically applied to PRs that change backend components label May 4, 2026
@@ -587,9 +587,6 @@ def _get_queryset_conditions(
"regressed_in_release": QCallbackCondition(
functools.partial(regressed_in_release_filter, projects=projects)
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: Removing the detector search filter alias breaks UI components and user-saved searches that still rely on it, causing them to return empty results.
Severity: HIGH

Suggested Fix

Reinstate the detector search alias to maintain backward compatibility. Alternatively, update all locations that use the detector: keyword, including UI components like ongoingIssues.tsx, and create a data migration to update existing SavedSearches and AlertRules to use the new query format.

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/search/snuba/backend.py#L588

Potential issue: The removal of the `detector` search filter alias will break existing
functionality that relies on it. Specifically, UI components like `ongoingIssues.tsx`
and `openPeriodIssues.tsx` contain hardcoded queries such as `is:unresolved
detector:${detector.id}`. With the alias removed, these queries will be interpreted as a
search for a tag named `detector`, which will not match any issues, causing these
components to display no results. This change also breaks existing user-created
`SavedSearches` and `AlertRules` that use the `detector:` keyword, causing them to fail
silently.

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

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

User-saved searches will fail, but this is before launch so we should reduce issues there. We are safe from the UI failing by breaking this work into many PRs.

@saponifi3d saponifi3d force-pushed the jcallender/aci/detector-to-monitor-part-2 branch from 9bbf802 to 0f7123e Compare May 4, 2026 23:33
@saponifi3d saponifi3d requested a review from a team as a code owner May 4, 2026 23:33
@saponifi3d saponifi3d force-pushed the jcallender/aci/detector-to-monitor-part-3 branch from fa9babc to d7470e3 Compare May 4, 2026 23:34
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 4, 2026

Backend Test Failures

Failures on 4ee6f61 in this run:

tests/sentry/search/events/test_filter.py::DetectorFilterTest::test_detector_filter_empty_listlog
[gw0] linux -- Python 3.13.1 /home/runner/work/sentry/sentry/.venv/bin/python3
src/sentry/search/snuba/executors.py:496: in _run_snuba_query
    bulk_query_results = bulk_raw_query(
src/sentry/utils/snuba.py:1172: in bulk_raw_query
    return _apply_cache_and_build_results(snuba_requests, use_cache=use_cache)
src/sentry/utils/snuba.py:1223: in _apply_cache_and_build_results
    query_results = _bulk_snuba_query([item[1] for item in to_query])
src/sentry/utils/snuba.py:1377: in _bulk_snuba_query
    raise clickhouse_error_codes_map.get(error["code"], QueryExecutionError)(
E   sentry.utils.snuba.QueryExecutionError: DB::Exception: Function 'in' is supported only if second argument is constant or table expression. Stack trace:
E   
E   0. DB::Exception::Exception(DB::Exception::MessageMasked&&, int, bool) @ 0x000000000f52449b
E   1. DB::Exception::Exception(PreformattedMessage&&, int) @ 0x0000000009fc506c
E   2. DB::Exception::Exception<String const&>(int, FormatStringHelperImpl<std::type_identity<String const&>::type>, String const&) @ 0x000000000a8c6b8b
E   3. DB::(anonymous namespace)::CollectSetsVisitor::visitImpl(std::shared_ptr<DB::IQueryTreeNode> const&) (.llvm.16608718889807852874) @ 0x0000000012fbd903
E   4. DB::InDepthQueryTreeVisitor<DB::(anonymous namespace)::CollectSetsVisitor, true>::visitChildren(std::shared_ptr<DB::IQueryTreeNode> const&) (.llvm.16608718889807852874) @ 0x0000000012fbc9b0
E   5. DB::InDepthQueryTreeVisitor<DB::(anonymous namespace)::CollectSetsVisitor, true>::visitChildren(std::shared_ptr<DB::IQueryTreeNode> const&) (.llvm.16608718889807852874) @ 0x0000000012fbc9bb
E   6. DB::InDepthQueryTreeVisitor<DB::(anonymous namespace)::CollectSetsVisitor, true>::visitChildren(std::shared_ptr<DB::IQueryTreeNode> const&) (.llvm.16608718889807852874) @ 0x0000000012fbc9bb
E   7. DB::Planner::buildPlanForQueryNode() @ 0x0000000013654e41
E   8. DB::Planner::buildQueryPlanIfNeeded() @ 0x00000000136520be
E   9. DB::executeQueryImpl(char const*, char const*, std::shared_ptr<DB::Context>, DB::QueryFlags, DB::QueryProcessingStage::Enum, DB::ReadBuffer*, std::shared_ptr<DB::IAST>&) @ 0x00000000139f8ab9
E   10. DB::executeQuery(String const&, std::shared_ptr<DB::Context>, DB::QueryFlags, DB::QueryProcessingStage::Enum) @ 0x00000000139f40c4
E   11. DB::TCPHandler::runImpl() @ 0x0000000014d2d60c
E   12. DB::TCPHandler::run() @ 0x0000000014d4b7f9
E   13. Poco::Net::TCPServerConnection::start() @ 0x000000001847f067
E   14. Poco::Net::TCPServerDispatcher::run() @ 0x000000001847f4b9
E   15. Poco::PooledThread::run() @ 0x000000001844b81b
E   16. Poco::ThreadImpl::runnableEntry(void*) @ 0x0000000018449cfd
E   17. ? @ 0x00007f11495c7ac3
E   18. ? @ 0x00007f1149658a04

During handling of the above exception, another exception occurred:
tests/sentry/search/events/test_filter.py:1571: in test_detector_filter_empty_list
    results = backend.query(
src/sentry/search/snuba/backend.py:433: in query
    query_results = query_executor.query(
src/sentry/search/snuba/executors.py:1089: in query
    snuba_groups, total = self.snuba_search(
src/sentry/search/snuba/executors.py:585: in snuba_search
    return _run_snuba_query()
src/sentry/search/snuba/executors.py:510: in _run_snuba_query
    bulk_query_results = bulk_raw_query(
src/sentry/utils/snuba.py:1172: in bulk_raw_query
    return _apply_cache_and_build_results(snuba_requests, use_cache=use_cache)
src/sentry/utils/snuba.py:1223: in _apply_cache_and_build_results
    query_results = _bulk_snuba_query([item[1] for item in to_query])
src/sentry/utils/snuba.py:1377: in _bulk_snuba_query
    raise clickhouse_error_codes_map.get(error["code"], QueryExecutionError)(
E   sentry.utils.snuba.QueryExecutionError: DB::Exception: Function 'in' is supported only if second argument is constant or table expression. Stack trace:
E   
... (19 more lines)
tests/sentry/issues/test_issue_search.py::ConvertDetectorValueTest::test_validlog
[gw1] linux -- Python 3.13.1 /home/runner/work/sentry/sentry/.venv/bin/python3
tests/sentry/issues/test_issue_search.py:354: in test_valid
    assert result[0].value.raw_value == ["412345"]
E   AssertionError: assert '412345' == ['412345']
E    +  where '412345' = SearchValue(raw_value='412345', use_raw_value=False).raw_value
E    +    where SearchValue(raw_value='412345', use_raw_value=False) = SearchFilter(key=SearchKey(name='detector'), operator='=', value=SearchValue(raw_value='412345', use_raw_value=False)).value
tests/sentry/search/events/test_filter.py::DetectorFilterTest::test_detector_filter_invalid_detectorlog
[gw1] linux -- Python 3.13.1 /home/runner/work/sentry/sentry/.venv/bin/python3
tests/sentry/search/events/test_filter.py:1509: in test_detector_filter_invalid_detector
    results = backend.query(
src/sentry/search/snuba/backend.py:433: in query
    query_results = query_executor.query(
src/sentry/search/snuba/executors.py:1089: in query
    snuba_groups, total = self.snuba_search(
src/sentry/search/snuba/executors.py:465: in snuba_search
    query_params = self._prepare_params_for_category(
src/sentry/search/snuba/executors.py:381: in _prepare_params_for_category
    snuba_query_params = strategy(
src/sentry/issues/search.py:174: in _query_params_for_error
    params = query_partial(
src/sentry/utils/snuba.py:1840: in aliased_query_params
    resolved_conditions = resolve_conditions(conditions, column_resolver)
src/sentry/utils/snuba.py:1768: in resolve_conditions
    replacement = resolve_condition(deepcopy(condition), column_resolver)
src/sentry/utils/snuba.py:1685: in resolve_condition
    index = get_function_index(cond)
src/sentry/utils/snuba.py:664: in get_function_index
    assert column_expr[i] in SAFE_FUNCTIONS or SAFE_FUNCTION_RE.match(column_expr[i]), (
E   AssertionError: =
tests/sentry/search/events/test_filter.py::DetectorFilterTest::test_detector_filter_single_detectorlog
[gw1] linux -- Python 3.13.1 /home/runner/work/sentry/sentry/.venv/bin/python3
tests/sentry/search/events/test_filter.py:1448: in test_detector_filter_single_detector
    results = backend.query(
src/sentry/search/snuba/backend.py:433: in query
    query_results = query_executor.query(
src/sentry/search/snuba/executors.py:1089: in query
    snuba_groups, total = self.snuba_search(
src/sentry/search/snuba/executors.py:465: in snuba_search
    query_params = self._prepare_params_for_category(
src/sentry/search/snuba/executors.py:381: in _prepare_params_for_category
    snuba_query_params = strategy(
src/sentry/issues/search.py:174: in _query_params_for_error
    params = query_partial(
src/sentry/utils/snuba.py:1840: in aliased_query_params
    resolved_conditions = resolve_conditions(conditions, column_resolver)
src/sentry/utils/snuba.py:1768: in resolve_conditions
    replacement = resolve_condition(deepcopy(condition), column_resolver)
src/sentry/utils/snuba.py:1685: in resolve_condition
    index = get_function_index(cond)
src/sentry/utils/snuba.py:664: in get_function_index
    assert column_expr[i] in SAFE_FUNCTIONS or SAFE_FUNCTION_RE.match(column_expr[i]), (
E   AssertionError: =
tests/sentry/search/events/test_filter.py::DetectorFilterTest::test_detector_filter_no_matcheslog
[gw0] linux -- Python 3.13.1 /home/runner/work/sentry/sentry/.venv/bin/python3
tests/sentry/search/events/test_filter.py:1491: in test_detector_filter_no_matches
    results = backend.query(
src/sentry/search/snuba/backend.py:433: in query
    query_results = query_executor.query(
src/sentry/search/snuba/executors.py:1089: in query
    snuba_groups, total = self.snuba_search(
src/sentry/search/snuba/executors.py:465: in snuba_search
    query_params = self._prepare_params_for_category(
src/sentry/search/snuba/executors.py:381: in _prepare_params_for_category
    snuba_query_params = strategy(
src/sentry/issues/search.py:174: in _query_params_for_error
    params = query_partial(
src/sentry/utils/snuba.py:1840: in aliased_query_params
    resolved_conditions = resolve_conditions(conditions, column_resolver)
src/sentry/utils/snuba.py:1768: in resolve_conditions
    replacement = resolve_condition(deepcopy(condition), column_resolver)
src/sentry/utils/snuba.py:1685: in resolve_condition
    index = get_function_index(cond)
src/sentry/utils/snuba.py:664: in get_function_index
    assert column_expr[i] in SAFE_FUNCTIONS or SAFE_FUNCTION_RE.match(column_expr[i]), (
E   AssertionError: =
tests/sentry/search/events/test_filter.py::DetectorFilterTest::test_detector_filter_negationlog
[gw0] linux -- Python 3.13.1 /home/runner/work/sentry/sentry/.venv/bin/python3
tests/sentry/search/events/test_filter.py:1531: in test_detector_filter_negation
    results = backend.query(
src/sentry/search/snuba/backend.py:433: in query
    query_results = query_executor.query(
src/sentry/search/snuba/executors.py:1089: in query
    snuba_groups, total = self.snuba_search(
src/sentry/search/snuba/executors.py:465: in snuba_search
    query_params = self._prepare_params_for_category(
src/sentry/search/snuba/executors.py:381: in _prepare_params_for_category
    snuba_query_params = strategy(
src/sentry/issues/search.py:174: in _query_params_for_error
    params = query_partial(
src/sentry/utils/snuba.py:1840: in aliased_query_params
    resolved_conditions = resolve_conditions(conditions, column_resolver)
src/sentry/utils/snuba.py:1768: in resolve_conditions
    replacement = resolve_condition(deepcopy(condition), column_resolver)
src/sentry/utils/snuba.py:1685: in resolve_condition
    index = get_function_index(cond)
src/sentry/utils/snuba.py:664: in get_function_index
    assert column_expr[i] in SAFE_FUNCTIONS or SAFE_FUNCTION_RE.match(column_expr[i]), (
E   AssertionError: !=
tests/sentry/search/events/test_filter.py::DetectorFilterTest::test_detector_filter_multiple_detectorslog
[gw1] linux -- Python 3.13.1 /home/runner/work/sentry/sentry/.venv/bin/python3
tests/sentry/search/events/test_filter.py:1480: in test_detector_filter_multiple_detectors
    assert len(results.results) == 2
E   assert 0 == 2
E    +  where 0 = len([])
E    +    where [] = <CursorResult: results=0>.results
tests/sentry/search/events/test_filter.py::DetectorFilterTest::test_detector_filter_with_other_filterslog
[gw1] linux -- Python 3.13.1 /home/runner/work/sentry/sentry/.venv/bin/python3
tests/sentry/search/events/test_filter.py:1550: in test_detector_filter_with_other_filters
    results = backend.query(
src/sentry/search/snuba/backend.py:433: in query
    query_results = query_executor.query(
src/sentry/search/snuba/executors.py:1089: in query
    snuba_groups, total = self.snuba_search(
src/sentry/search/snuba/executors.py:465: in snuba_search
    query_params = self._prepare_params_for_category(
src/sentry/search/snuba/executors.py:381: in _prepare_params_for_category
    snuba_query_params = strategy(
src/sentry/issues/search.py:174: in _query_params_for_error
    params = query_partial(
src/sentry/utils/snuba.py:1840: in aliased_query_params
    resolved_conditions = resolve_conditions(conditions, column_resolver)
src/sentry/utils/snuba.py:1768: in resolve_conditions
    replacement = resolve_condition(deepcopy(condition), column_resolver)
src/sentry/utils/snuba.py:1685: in resolve_condition
    index = get_function_index(cond)
src/sentry/utils/snuba.py:664: in get_function_index
    assert column_expr[i] in SAFE_FUNCTIONS or SAFE_FUNCTION_RE.match(column_expr[i]), (
E   AssertionError: =

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