Skip to content

Alert notification sample events ignore saved-search filters — alerts show unrelated log lines as evidence #3059

Closed

Description

@markus-sanness

What happened?

A saved search scoped via the filter bar (the filters array) instead of the where clause evaluates its alerts correctly — the threshold count respects the filters — but the sample events rendered into the notification body are queried without the filters. The alert fires saying "1 lines found" and then shows five arbitrary, unrelated log lines from the time window as evidence (in our case: Kubernetes reloader/info noise with empty service fields, while the actually-matched event was a service error).

Expected: the sample lines come from the same row set the alert counted — the sample query should apply savedSearch.filters the same way evaluation does.

Cause: the two paths build their queries differently. Alert evaluation
(packages/api/src/tasks/checkAlerts/index.ts, getChartConfigFromAlert)
passes filters: savedSearch.filters into the shared buildSearchChartConfig
— per its own comment, so all paths assemble configs "identically". The sample
fetch (packages/api/src/tasks/checkAlerts/template.ts) hand-builds its
chartConfig from savedSearch.where/whereLanguage only; filters is never
referenced in that file. Routing the sample fetch through the same shared
builder would fix it.

Steps to reproduce

  1. Create a saved search on a log source with an empty where, scoped entirely via filter-bar conditions, e.g. ServiceName = 'my-service', ResourceAttributes['deployment.environment.name'] = 'production', SeverityText IN ('error','fatal')
  2. Attach an alert (at least 1 line within 5 minutes) with a generic or incident.io webhook channel
  3. Wait for one matching event; the alert fires with the correct count ("1 lines found")
  4. Inspect the delivered webhook body: the code fence contains up to 5 unfiltered lines from the window instead of the matched event

How are you running HyperDX?

ClickStack on ClickHouse Cloud (managed, current version as of Sept 2026 — ~2.37 era).

Where does it show up?

In the delivered alert notification body (webhook payload description / incident.io alert description) — both generic and incident.io webhook types. The search UI itself displays correct results for the same conditions.

Logs

Sample from a real firing (redacted): alert scoped to ServiceName = 'customer-idp' AND ResourceAttributes['deployment.environment.name'] = 'production' AND SeverityText IN ('error','fatal'); exactly 1 matching error existed in the window (verified by querying ClickHouse directly), yet the body contained:

"2026-09-02T11:18:39.000000000Z","","warn","","","Back-off restarting failed container reloader-reloader in pod reloader-…"
"2026-09-02T11:18:39.105628798Z","","info","","","[WARNING] No files matching import glob pattern: custom/*.override"

Note the empty service fields — none of these rows match the search's filters. Moving the same conditions into the where clause makes the samples correct, which is our current workaround.

Activity

  1. wrn14897 commented on Sep 8, 2026

    @wrn14897
    Contributor

    @markus-sanness. Thanks for reporting this bug! If you’re interested in contributing a fix, we’d be happy to prioritize reviewing your pull request.

  2. Tyagiquamar commented on Sep 10, 2026

    @Tyagiquamar
    Contributor

    Implementation plan for this issue (per repo workflow). Problem: the saved-search sample fetch in renderAlertTemplate hand-builds its chart config from where/whereLanguage only, while evaluation goes through buildSearchChartConfig with savedSearch.filters. Fix: add filters: savedSearch.filters map-spread to the sample chartConfig literal in packages/api/src/tasks/checkAlerts/template.ts so renderChartConfig applies the same row set the alert counted. No change to TILE/INLINE paths. Tests: extend packages/api/src/tasks/checkAlerts/tests/renderAlertTemplate.int.test.ts with a saved search carrying filters, asserting samples come from the filtered set. Risk: filters referencing aliases need computeAliasWithClauses, which the sample path already calls. Will open the PR with an agent/ branch and a changeset once my intro (#3101) is vouched.

  3. added a commit that references this issue on Sep 14, 2026
    edb693a
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions