Repository navigation
fix(cli): Explain Explore aggregates rejected for their argument - #1927
Merged
Merged
Conversation
When Sentry rejects the function and argument of a user --field or --sort (a string attribute in p75, transaction.duration on the transactions dataset, a non-numeric errors column, an invalid count_if argument), raise a ValidationError with the server detail and a recovery hint instead of a raw 400 ApiError. Rejections of CLI-generated expressions stay ApiErrors. Refs CLI-10 Co-Authored-By: Miguel Betegon <miguel.betegon@sentry.io>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
The Events endpoint returns event_search.py parser failures unwrapped
("Invalid quote at ...", "Parse error at ...", '"is:" queries are not
supported ...', "timestamp: Invalid date: ..."). Only the issue-search
wrapper "Error parsing search query" was recognized, so a typo in a
user's explore/span/log/trace --query surfaced as a raw 400 and was
reported to Sentry as a CLI bug (CLI-10).
Recognize the grammar-level parser messages too, so toSearchQueryError
turns them into a query ValidationError when the user supplied --query.
Co-Authored-By: Miguel Betegon <miguel.betegon@sentry.io>
BYK
requested changes
Nov 4, 2026
This was referenced Nov 4, 2026
Replace the list of parser message patterns with the "invalid_search_query" code the Events endpoint now returns next to "detail" (getsentry/sentry#129957). ApiError keeps the error body's code; its optional enriched403 flag moves into an options object to make room. Refs CLI-10
…-parse-errors # Conflicts: # packages/cli/src/lib/api/infrastructure.ts
BYK
pushed a commit
to getsentry/sentry
that referenced
this pull request
Nov 4, 2026
When a query function rejects one of its arguments, the 400 now also carries `code`, `function`, and `argument` alongside `detail`. Clients can then tell which `field`/`orderby` expression to fix without regex-matching the message. `detail` stays the same, so existing consumers aren't affected. This covers both resolvers: - EAP (`search/eap/resolver.py`): argument has the wrong type, isn't in the allowlist, or fails a validator. - Discover (`search/events/fields.py`): `<fn>: <arg> argument invalid: …`. Context: the Sentry CLI currently regex-matches these messages to tell a user's typo apart from a CLI bug ([getsentry/toolkit#1927](getsentry/toolkit#1927 (comment)), CLI-10). Once this lands, the CLI can key off `code`/`function`/`argument` instead. ### Before ``` GET /api/0/organizations/org-slug/events/?dataset=spans&field=p75(span.description) 400 {"detail": "span.description is invalid for parameter 1 in p75. Its a string type field, but it must be one of these types: {...}"} GET /api/0/organizations/org-slug/events/?dataset=errors&field=min(title) 400 {"detail": "min: column argument invalid: title is not a numeric column"} ``` ### After ``` GET /api/0/organizations/org-slug/events/?dataset=spans&field=p75(span.description) 400 {"detail": "span.description is invalid for parameter 1 in p75. Its a string type field, but it must be one of these types: {...}", "code": "invalid_function_argument", "function": "p75", "argument": "span.description"} GET /api/0/organizations/org-slug/events/?dataset=errors&field=min(title) 400 {"detail": "min: column argument invalid: title is not a numeric column", "code": "invalid_function_argument", "function": "min", "argument": "title"} ``` `argument` is the argument exactly as the client sent it (e.g. `tags[foo,number]`), not the resolved alias. <!-- junior-request-attribution:start --> via @BYK. <!-- junior-request-attribution:end --> <!-- junior-session-footer:start --> <!-- junior-conversation-id:agent%3A61f1063c1e971e700aaa2c3a3c12100a --> -- [View Session](https://junior-prod.sentry.dev/conversations/agent%3A61f1063c1e971e700aaa2c3a3c12100a) [[Sentry]](https://sentry.sentry.io/explore/conversations/agent%3A61f1063c1e971e700aaa2c3a3c12100a/?project=4510944073809921) <!-- junior-session-footer:end --> Co-authored-by: sentry-junior[bot] <264270552+sentry-junior[bot]@users.noreply.github.com>
…rs' into fix/cli-explore-attribute-type-errors
Replace the detail-message patterns with the structured fields that getsentry/sentry#129954 adds to function-argument 400s: code invalid_function_argument plus function and argument. A 400 without the code stays an ApiError.
Contributor
Author
|
Done. getsentry/sentry#129954 (merged) now returns |
…bute-type-errors # Conflicts: # packages/cli/src/lib/api/infrastructure.ts # packages/cli/src/lib/errors.ts # packages/cli/test/lib/api-client.coverage.test.ts # packages/cli/test/lib/api/infrastructure.test.ts
BYK
approved these changes
Nov 4, 2026
BYK
enabled auto-merge (squash)
November 4, 2026 21:56
This was referenced Nov 4, 2026
Merged
BYK
added a commit
to getsentry/sentry
that referenced
this pull request
Nov 4, 2026
#129981) The `invalid_function_argument` 400 (#129954) can now include a `hint` that suggests a fix. `InvalidFunctionArgumentQuery` takes an optional `hint`, and `handle_query_errors` adds it to the body only when it's set. All other bodies stay the same. The first hint is for `transaction.duration` passed to a numeric function on the spans dataset. Transactions are stored as spans, which keep their duration in `span.duration`. This moves the hint out of the Sentry CLI, as decided on [getsentry/toolkit#1927](getsentry/toolkit#1927 (comment)) (CLI-10). ### Before ``` GET /api/0/organizations/org-slug/events/?dataset=spans&field=sum(transaction.duration) 400 {"detail": "transaction.duration is invalid for parameter 1 in sum. Its a string type field, but it must be one of these types: {...}", "code": "invalid_function_argument", "function": "sum", "argument": "transaction.duration"} ``` ### After ``` GET /api/0/organizations/org-slug/events/?dataset=spans&field=sum(transaction.duration) 400 {"detail": "transaction.duration is invalid for parameter 1 in sum. Its a string type field, but it must be one of these types: {...}", "code": "invalid_function_argument", "function": "sum", "argument": "transaction.duration", "hint": "Use span.duration instead of transaction.duration on the spans dataset."} ``` <!-- junior-request-attribution:start --> via @BYK. <!-- junior-request-attribution:end --> <!-- junior-session-footer:start --> <!-- junior-conversation-id:agent%3A61f1063c1e971e700aaa2c3a3c12100a --> -- [View Session](https://junior-prod.sentry.dev/conversations/agent%3A61f1063c1e971e700aaa2c3a3c12100a) [[Sentry]](https://sentry.sentry.io/explore/conversations/agent%3A61f1063c1e971e700aaa2c3a3c12100a/?project=4510944073809921) <!-- junior-session-footer:end --> Co-authored-by: sentry-junior[bot] <264270552+sentry-junior[bot]@users.noreply.github.com> Co-authored-by: BYK <126780+BYK@users.noreply.github.com>
BYK
added a commit
that referenced
this pull request
Nov 4, 2026
…nts (#1966) Follow-up to #1927 (CLI-10), as decided in [this review thread](#1927 (comment)). The `invalid_function_argument` 400 can now carry a `hint` ([getsentry/sentry#129981](getsentry/sentry#129981)). `readErrorFields` reads it next to `function` and `argument`, and `sentry explore` shows it as the suggestion. The CLI's own `transaction.duration` → `span.duration` mapping is gone, since the server owns that text now. The `tags[X,number]` / `sentry attribute list` hint names CLI commands and flags, so it stays in the CLI as the fallback when there's no `hint`. Until sentry#129981 deploys, `transaction.duration` gets the generic fallback hint instead of the `span.duration` one. ### Before ``` $ sentry explore my-org/ --dataset transactions -F 'sum(transaction.duration)' Error: Sentry rejected --field "sum(transaction.duration)" for dataset "spans". transaction.duration is invalid for parameter 1 in sum. Its a string type field, but it must be one of these types: {'number', 'duration'} Try: Use span.duration instead of transaction.duration. Transactions are queried as spans, which store their duration in span.duration. ``` ### After With the server's `hint`: ``` $ sentry explore my-org/ --dataset transactions -F 'sum(transaction.duration)' Error: Sentry rejected --field "sum(transaction.duration)" for dataset "spans". transaction.duration is invalid for parameter 1 in sum. Its a string type field, but it must be one of these types: {'number', 'duration'} Try: Use span.duration instead of transaction.duration on the spans dataset. ``` Without it (before sentry#129981 deploys): ``` Try: sum() does not accept transaction.duration on dataset "spans": it may not exist there, or may not have the type sum() needs. Reference a numeric custom attribute with its type, e.g. tags[transaction.duration,number]; to check the key and its type, run: sentry attribute list <org>/ transaction.duration --dataset spans ``` <!-- junior-request-attribution:start --> via @BYK. <!-- junior-request-attribution:end --> <!-- junior-session-footer:start --> <!-- junior-conversation-id:agent%3A61f1063c1e971e700aaa2c3a3c12100a --> -- [View Session](https://junior-prod.sentry.dev/conversations/agent%3A61f1063c1e971e700aaa2c3a3c12100a) [[Sentry]](https://sentry.sentry.io/explore/conversations/agent%3A61f1063c1e971e700aaa2c3a3c12100a/?project=4510944073809921) <!-- junior-session-footer:end --> Co-authored-by: sentry-junior[bot] <264270552+sentry-junior[bot]@users.noreply.github.com> Co-authored-by: BYK <126780+BYK@users.noreply.github.com>
7 tasks done
This branch was successfully 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.
Part of CLI-10 ("API request failed: 400"). When
sentry exploresends a user--field/--sortaggregate that Sentry rejects because of its argument, the CLI shows a raw 400 and reports it as a CLI bug. These are input mistakes: a string attribute in a numeric aggregate,transaction.durationon--dataset transactions(which queries spans), a non-numeric errors column, or an invalidcount_ifargument.The CLI now reads the structured fields that getsentry/sentry#129954 (merged) adds to these 400s,
"code": "invalid_function_argument"plusfunctionandargument, instead of matching message text.ApiErrorkeeps them next tocode. When they name the same function and argument as a user expression that reached the request,toExploreFieldError(#1661) raises aValidationErrorthat keeps the server detail and adds a hint. Rejections of default or generated expressions, and 400s without the code (servers before that deploy), stayApiErrors. The #1661 hints are unchanged.Builds on #1936 for
ApiError.code. Merge that first.Before
After
With the server sending
code,functionandargument:I captured these outputs against a local stub that returns each 400 body.
via @BYK.
--
View Session [Sentry]