Skip to content

fix(incidents): Handle unaliased crash-free aggregates in charts#118619

Open
sentry[bot] wants to merge 2 commits into
masterfrom
seer/fix/incidents-unaliased-aggregates
Open

fix(incidents): Handle unaliased crash-free aggregates in charts#118619
sentry[bot] wants to merge 2 commits into
masterfrom
seer/fix/incidents-unaliased-aggregates

Conversation

@sentry

@sentry sentry Bot commented Jun 27, 2026

Copy link
Copy Markdown
Contributor

This PR addresses a KeyError occurring in sentry.workflow_engine.tasks.trigger_action when generating charts for metric alerts.

The root cause is that the fetch_metric_alert_sessions_data function, used for rendering metric alert charts, performs a strict lookup in the SESSION_AGGREGATE_TO_FIELD dictionary. This dictionary expects crash-free aggregate strings to include the AS _crash_rate_alert_aggregate alias (e.g., "percentage(sessions_crashed, sessions) AS _crash_rate_alert_aggregate").

However, it was found that metric alert rules, particularly those created via API or Terraform, can sometimes store the aggregate string without this alias (e.g., "percentage(sessions_crashed, sessions)"). When such an unaliased aggregate is passed to the charting logic, the lookup fails, resulting in a KeyError.

The solution implemented is to add the unaliased versions of the crash-free session and user aggregates to the SESSION_AGGREGATE_TO_FIELD dictionary in both the backend (src/sentry/incidents/charts.py) and frontend (static/app/views/alerts/utils/index.tsx). Additionally, the isSessionAggregate function in the frontend was updated to recognize these unaliased strings. This allows the charting code to correctly resolve the aggregate to its corresponding session field, regardless of whether the alias is present in the stored aggregate string, thus preventing the KeyError and ensuring charts render as expected.

Fixes SENTRY-5M4G

Legal Boilerplate

Look, I get it. The entity doing business as "Sentry" was incorporated in the State of Delaware in 2015 as Functional Software, Inc. and is gonna need some rights from me in order to utilize my contributions in this here PR. So here's the deal: I retain all rights, title and interest in and to my contributions, and by keeping this boilerplate intact I confirm that Sentry can use, modify, copy, and redistribute my contributions, under Sentry's choice of terms.

Fixes SENTRY-5M4G

Comment @sentry <feedback> on this PR to have Autofix iterate on the changes.

@sentry sentry Bot requested a review from a team as a code owner June 27, 2026 10:42
@github-actions github-actions Bot added the Scope: Backend Automatically applied to PRs that change backend components label Jun 27, 2026
@github-actions github-actions Bot added the Scope: Frontend Automatically applied to PRs that change frontend components label Jun 28, 2026
@github-actions

Copy link
Copy Markdown
Contributor

🚨 Warning: This pull request contains Frontend and Backend changes!

It's discouraged to make changes to Sentry's Frontend and Backend in a single pull request. The Frontend and Backend are not atomically deployed. If the changes are interdependent of each other, they must be separated into two pull requests and be made forward or backwards compatible, such that the Backend or Frontend can be safely deployed independently.

Have questions? Please ask in the #discuss-dev-infra channel.

Comment on lines 122 to 126
[SessionsAggregate.CRASH_FREE_USERS]: SessionFieldWithOperation.USERS,
'percentage(sessions_crashed, sessions)': SessionFieldWithOperation.SESSIONS,
'percentage(users_crashed, users)': SessionFieldWithOperation.USERS,
};

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.

Bug: Chart rendering for metric alerts with unaliased session aggregates is broken, resulting in a missing heading and an incorrect series name due to incomplete lookup objects and faulty string matching.
Severity: MEDIUM

Suggested Fix

Update SESSION_AGGREGATE_TO_HEADING in chart/index.tsx to include mappings for the unaliased aggregate strings. In wizard/utils.tsx, modify getAlertTypeFromAggregateDataset to correctly match unaliased aggregates, possibly by checking if the identifier includes the aggregate or by using a more robust matching method instead of aggregate.includes(identifier).

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: static/app/views/alerts/utils/index.tsx#L122-L126

Potential issue: When a metric alert rule with an unaliased session aggregate (e.g.,
`'percentage(sessions_crashed, sessions)'`) is rendered, two issues occur in the chart.
First, the `SESSION_AGGREGATE_TO_HEADING` object lacks entries for these unaliased
strings, causing the chart's `totalCountLabel` to be `undefined` and rendering an empty
heading. Second, the `getAlertTypeFromAggregateDataset` function fails to correctly
identify the alert type because its string matching logic
(`aggregate.includes(aliased_identifier)`) does not work when the `aggregate` is shorter
than the identifier. This results in the function returning a default value, causing the
chart series to be labeled with an incorrect name, such as 'Custom Transactions'. Both
issues stem from incomplete handling of unaliased aggregates introduced for API- or
Terraform-created alerts.

Also affects:

  • static/app/views/alerts/rules/metric/triggers/chart/index.tsx:121~122
  • static/app/views/alerts/wizard/utils.tsx

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

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 Scope: Frontend Automatically applied to PRs that change frontend components

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants