fix(alerts): return 400 instead of 500 when creating alert with unsupported dataset#119456
fix(alerts): return 400 instead of 500 when creating alert with unsupported dataset#119456billyvg wants to merge 2 commits into
Conversation
…ported dataset
When a user POSTs to /api/0/organizations/{org}/alert-rules/ with
`dataset=sessions` (or any dataset not in `query_datasets_to_type`),
the lookup `query_datasets_to_type[dataset]` raises a KeyError that
bubbles up as an unhandled 500. Add an explicit ValidationError before
the dict lookup so callers get a well-formed 400 with a helpful message
listing the valid datasets.
Fixes SENTRY-5PEF
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LjN9gb92hUE6jTqQ9dkjAm
CamelSnakeModelSerializer converts error dict keys to camelCase, so non_field_errors becomes nonFieldErrors in the errors dict. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LjN9gb92hUE6jTqQ9dkjAm
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 483e8b3. Configure here.
| raise serializers.ValidationError( | ||
| "Invalid dataset for alerts. Valid datasets are: %s" | ||
| % ", ".join(sorted(d.name.lower() for d in query_datasets_to_type)) | ||
| ) |
There was a problem hiding this comment.
Error lists unusable dataset names
Low Severity
The new validation error builds its allowed-dataset list from enum .name.lower() values, but the API accepts dataset .value strings. For PerformanceMetrics and EventsAnalyticsPlatform, those differ (performancemetrics vs generic_metrics, eventsanalyticsplatform vs events_analytics_platform), so the 400 response advertises identifiers clients cannot submit. Field-level validate_dataset already lists .value correctly.
Reviewed by Cursor Bugbot for commit 483e8b3. Configure here.


Summary
Fixes SENTRY-5PEF —
KeyError: <Dataset.Sessions: 'sessions'>insnuba_query_validator.pyRoot cause: When a user POSTs to
/api/0/organizations/{org}/alert-rules/withdataset=sessions(or any dataset absent fromquery_datasets_to_type), the dict lookup on line 321 raises an unhandledKeyErrorthat propagates as a 500.Dataset.Sessionswas removed fromquery_datasets_to_type(which now only containsEvents,Transactions,PerformanceMetrics,Metrics, andEventsAnalyticsPlatform), but external API clients still senddataset=sessions. This has been happening since at least 2026-05-06 with 8 unique users affected.Fix: Add an explicit
dataset not in query_datasets_to_typecheck that raises aserializers.ValidationError(→ HTTP 400) with a message listing the valid datasets, before the dict lookup that was previously crashing.Evidence:
sentry/snuba/snuba_query_validator.py:321in_validate_query—query_datasets_to_type[dataset]raisesKeyErrorwhen dataset isDataset.SessionsTest plan
test_invalid_dataset_sessions_returns_validation_errortotests/sentry/snuba/test_validators.pycovering the exact failing caseSnubaQueryValidatorTesttests continue to passClaude session: https://claude.ai/code/session_01LjN9gb92hUE6jTqQ9dkjAm
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.
Generated by Claude Code