Skip to content

feat(dashboards): Repair MCP dashboard widget filters#115543

Open
gggritso wants to merge 2 commits into
masterfrom
georgegritsouk/dain-1673-backfill-mcp-dashboard-widget-filters
Open

feat(dashboards): Repair MCP dashboard widget filters#115543
gggritso wants to merge 2 commits into
masterfrom
georgegritsouk/dain-1673-backfill-mcp-dashboard-widget-filters

Conversation

@gggritso
Copy link
Copy Markdown
Member

@gggritso gggritso commented May 14, 2026

A consequence of getsentry/relay#5961 is that span.name of MCP server spans went from "mcp.server" (incorrect) to actual names like "tool/call whatever". Any conditions like "span.name:mcp.server" will now always be false. Unfortunately this breaks any dashboards that were cloned from our pre-built ones. This adds a migration to repair people's dashboards. span.op is correctly "mcp.server" so that condition is safe, and equivalent to the previous one. The prebuilt configs were fixed in #115540.

There are ~100 of these widgets, so it's a fast migration.

References DAIN-1673.

Replace `span.name:mcp.server` with `span.op:mcp.server` in every
DashboardWidgetQuery.conditions value. A recent Relay change corrected
the `name` of MCP spans, breaking the old filter. The prebuilt configs
were already fixed in code, but widgets persisted from copies or hand-
edited filters still carry the broken substring.

Post-deployment, idempotent, scans only rows that contain the old
substring.

Refs DAIN-1673
Co-Authored-By: Claude <noreply@anthropic.com>
@linear-code
Copy link
Copy Markdown

linear-code Bot commented May 14, 2026

DAIN-1673

@github-actions github-actions Bot added the Scope: Backend Automatically applied to PRs that change backend components label May 14, 2026
@gggritso gggritso changed the title feat(dashboards): Backfill MCP dashboard widget filters feat(dashboards): Repair MCP dashboard widget filters May 14, 2026
@github-actions
Copy link
Copy Markdown
Contributor

This PR has a migration; here is the generated SQL for src/sentry/migrations/1095_backfill_mcp_dashboard_widget_filters.py

for 1095_backfill_mcp_dashboard_widget_filters in sentry

--
-- Raw Python operation
--
-- THIS OPERATION CANNOT BE WRITTEN AS SQL

Add a TestMigrations case that covers the substring replacement: bare
match, match alongside `has:` clauses, match embedded in a longer
condition, rows already using `span.op:`, and unrelated rows.

Refs DAIN-1673
Co-Authored-By: Claude <noreply@anthropic.com>
@github-actions

This comment was marked as outdated.

gggritso added a commit that referenced this pull request May 14, 2026
…5540)

getsentry/relay#5961 correctly (but
unexpectedly) changed the `name` attribute for MCP spans, which caused
our pre-built dashboards to stop loading data, because the
`span.name:mcp.server` filter is no longer valid. Instead, we need to
use `span.op` which is less semantic but is actually correct!

I also have a migration to repair existing widgets, there are only ~100:
#115543

References
[DAIN-1673](https://linear.app/getsentry/issue/DAIN-1673/mcp-pre-built-dashboards-use-incorrect-filters).

Co-authored-by: Claude <noreply@anthropic.com>
@gggritso gggritso requested a review from a team May 14, 2026 16:15
@gggritso gggritso marked this pull request as ready for review May 14, 2026 16:16
@gggritso gggritso requested a review from a team as a code owner May 14, 2026 16:16
Comment on lines +33 to +35
queryset = DashboardWidgetQuery.objects.filter(conditions__contains=_OLD_FILTER).only(
"id", "conditions"
)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think this query will run fast enough to not time out, since the table is only 1.2m rows

Comment on lines +33 to +35
queryset = DashboardWidgetQuery.objects.filter(conditions__contains=_OLD_FILTER).only(
"id", "conditions"
)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I'd recommend .values_list instead of .only to just fetch the values you need.

queryset = DashboardWidgetQuery.objects.filter(conditions__contains=_OLD_FILTER).only(
"id", "conditions"
)
for row in RangeQuerySetWrapperWithProgressBarApprox(queryset):
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

RangeQuerySetWrapperWithProgressBarApprox only works when you want to iterate the whole table. You don't really need to use this at all if you're querying only 100ish rows.

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.

2 participants