Repository navigation
fix(cli): Send native detector datasets and conditions for metric alerts - #1591
Merged
Merged
Conversation
`sentry alert metrics create/edit` moved onto the detectors API but still sent the legacy alert-rule payload: CLI dataset names (`spans`, `errors`) that the detector `SnubaQueryValidator` rejects, and legacy trigger objects as condition-group conditions that lack the required `type`. There was also no way to target logs. - Map CLI datasets onto native data sources (errors/events -> events, spans/logs -> events_analytics_platform with trace_item_span/trace_item_log, sessions/metrics -> crash-rate metrics) and add the `logs` dataset. - Map them back on read so list/view show CLI names and edit keeps log alerts on trace_item_log. - Translate alertThreshold triggers into threshold + resolution conditions; pass native detector conditions through. - Reject trigger actions (the detector API drops them) and add `--workflow` to connect existing alerts. Fixes #1588 Co-Authored-By: Burak Yigit Kaya <burak.kaya@sentry.io>
|
The latest updates on your projects. Learn more about Vercel for GitHub. 1 Skipped Deployment
|
…tors The edit baseline flattened the detector to a CLI dataset name, so a rename or status change on an EAP monitor the CLI does not model (e.g. `trace_item_metric`) rebuilt its data source with span defaults. Carry the stored `eventTypes`/`queryType` through the baseline and reuse them for non-CLI datasets.
BYK
requested changes
Oct 22, 2026
Address review on #1591: - Add `@sentry/toolkit-core/metric-monitor` with the native detector datasets, threshold operators, priorities, and per-signal data sources (from the Sentry validators, since `@sentry/api` types data sources and conditions as `unknown[]`). MCP's metric monitor schemas now use it too. - Add `src/types/metric-alert.ts` as the single CLI dataset table: the `--dataset` help, validation, aliases, write mapping, and read-back name are all derived from it. - Validate `--trigger` with Valibot schemas and pass the typed result to the detector body builder, replacing the ad-hoc checks and casts.
An empty eventTypes list matched any CLI dataset on the same native dataset, so EAP monitors without event types read back as spans and an edit rewrote them onto trace_item_span. Only resolve a CLI name for empty event types when the native dataset is unambiguous, and keep missing event types empty on edit instead of defaulting to spans.
BYK
reviewed
Oct 22, 2026
Edits always sent config { detectionType: static }, which replaced the
stored config and turned percent and dynamic detectors into static ones
(and deletes Seer data for dynamic detectors). Carry the stored detector
config through the edit baseline and send it back; creates still default
to static detection.
Contributor
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 77bd980. Configure here.
Edits resent the stored detector config even when --trigger supplied alertThreshold triggers, so percent detectors read the thresholds as percent comparisons and dynamic detectors got static conditions the backend rejects. Threshold triggers are static thresholds, so send a static config with them; native conditions and trigger-less edits keep the stored config.
BYK
approved these changes
Oct 22, 2026
BYK
pushed a commit
that referenced
this pull request
Nov 2, 2026
…ggers (#1818) In CLI releases up to 0.47.0, `sentry alert metrics create/edit` invoked `validateMetricTriggers`, which required every trigger to include a non-empty `actions` array and failed callers (typically AI coding agents) sending `actions: []` with `ValidationError: Each trigger must include a non-empty actions array.` Commit 5b7ea24 (#1591) migrated metric alert triggers to native detector conditions and introduced `ThresholdTriggerSchema` using `maxLength(0)` for actions, accepting `actions: []` and omitting actions from the detector conditions payload. This PR locks in the fix ahead of release with regression tests: - Asserts `parseMetricTriggers` accepts triggers containing empty `actions: []` arrays without error. - Asserts `createMetricAlertRule` strips empty trigger actions when constructing detector conditions. <!-- SEER_FIXES_SENTRY_ISSUE --> Fixes [CLI-20K](https://sentry.sentry.io/issues/7547567251/?seerDrawer=true) <!-- /SEER_FIXES_SENTRY_ISSUE --> <sub>`@sentry <feedback>`: Autofix iterates on these changes</sub> <sub>`@sentry stop iterating`: Autofix stops iterating on this run</sub> <sub>This PR was automatically generated by Sentry. You can [adjust this setting](https://sentry.sentry.io/settings/projects/cli/seer/) at any time.</sub> Co-authored-by: sentry[bot] <39604003+sentry[bot]@users.noreply.github.com>
BYK
pushed a commit
that referenced
this pull request
Nov 4, 2026
…on (#1930) Fixes the scan-scope half of [CLI-1ES](https://sentry.sentry.io/issues/7438547903/) (`scandir` errors, ~20k events). The `findProjectRoot` spans on the failing events show the CLI isn't failing inside projects. It's walking roots that aren't projects at all: - **`$HOME` with `reason: language`**: a stray `~/package.json` makes `$HOME` the project root, including for runs that start in a marker-less subdir like `~/.agent/workspaces/<id>`. The #1591 guard only checks `reason === "fallback"`, so these runs still walk `~/Library/CloudStorage`, `~/OrbStack`, OneDrive FUSE mounts, and `~/Documents/*.trace`. That's where the ETIMEDOUT / EIO / errno -11 / ECANCELED events come from. It can also pick up an unrelated DSN from anywhere under `$HOME`. - **`/tmp` with `reason: fallback`**: this walks other processes' FUSE mounts (AppImage `/tmp/.mount_*`, FreeRDP clipboard dirs), which fail with ENOTCONN. `shouldSkipDownwardScan()` now skips the file scan whenever the root is `$HOME`, an ancestor of `$HOME`, or a shared temp root, no matter which marker picked it. `SENTRY_DSN` still works. A project with a marker inside `/tmp` still gets scanned. **Before**: `detectAllDsns()` with `~/package.json` and a leftover `~/notes/old-demo.ts`, run from `~` or `~/.agent/ws1`: ```json { "projectRoot": "~", "reason": "language", "detected": ["https://abc@o1.ingest.sentry.io/1 (notes/old-demo.ts)"] } ``` **After**: same setup, `sentry issue list --verbose`: ``` [debug] [resolve-target] No config defaults set, trying DSN auto-detection [debug] [dsn] Skipping DSN file scan: project root ~ (language) is the home directory, an ancestor of it, or a shared temp directory [debug] [resolve-target] No DSNs found in source code or env files, trying directory name inference ``` ```json { "projectRoot": "~", "reason": "language", "detected": [] } ``` Tradeoff: a marker-less directory under a `$HOME` that has a marker no longer gets scanned. Before this change it scanned all of `$HOME`. `SENTRY_DSN`, `.sentryclirc`, or a project marker in that directory covers it. <!-- junior-request-attribution:start --> via **bete**. <!-- junior-request-attribution:end --> <!-- junior-session-footer:start --> <!-- junior-conversation-id:slack%3AC0C615WFS9G%3A1793783876.619939 --> -- [View Session](https://junior-prod.sentry.dev/conversations/slack%3AC0C615WFS9G%3A1793783876.619939) [[Sentry]](https://sentry.sentry.io/explore/conversations/slack%3AC0C615WFS9G%3A1793783876.619939/?project=4510944073809921) <!-- junior-session-footer:end --> Co-authored-by: sentry-junior[bot] <264270552+sentry-junior[bot]@users.noreply.github.com> Co-authored-by: Miguel Betegon <miguel.betegon@sentry.io>
This branch was previously deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

Fixes #1588.
The detectors migration (getsentry/cli#1275, #1338) fixed the list/view mismatch and the legacy
/alert-rules/calls from the issue. Butalert metrics create/editstill sends the legacy payload to the detectors API, and the backend rejects it:spans/errors/sessionsas-is.SnubaQueryValidatoronly accepts nativeDatasetvalues that matchqueryType(errorsisn't aDataset, andspansisn't valid forqueryType: 1). There was also no way to pick logs.{alertThreshold, actions}objects are passed as condition-group conditions verbatim.MetricIssueComparisonConditionValidatorrequirestype/comparison/conditionResult, so any--triggerfails.What changed:
errors/events→events(type 0),spans→events_analytics_platform+trace_item_span,logs(new) →events_analytics_platform+trace_item_log,sessions/metrics→metrics(crash rate, type 2). Reads map them back, solist/viewshow the namescreateaccepts. Aneditround-trip also keeps a log alert ontrace_item_loginstead of turning it into a span alert.alertThresholdtriggers (optionallabel,resolveThreshold,thresholdType) become threshold conditions plus the one resolution condition the validator requires. Native detector conditions (withtype) pass through untouched. Both shapes are validated with Valibot schemas.actionsnow fail with a clear error instead of being dropped silently. A new--workflow <id>flag oncreate/editconnects existing alerts throughworkflowIds.@sentry/toolkit-core/metric-monitormodule, which MCP's metric monitor schemas now use too.@sentry/apitypes data sources and conditions asunknown[], so there's nothing to import from it. Swapping this module for generated@sentry/apitypes is tracked in Use typed detector schemas from @sentry/api for metric monitors #1595. On the CLI side, one dataset table insrc/types/metric-alert.tsdrives--datasethelp, validation, aliases, and both mapping directions.For data sources the CLI doesn't model (for example trace metrics),
editkeeps the storedeventTypesandqueryTypeinstead of switching the monitor to spans.via BYK.
--
View Junior Session [Sentry]