Repository navigation
fix(mcp): Rewrite AND/OR in search_issues queries before calling Sentry - #1671
Merged
Merged
Conversation
The issues endpoint rejects AND/OR ("Boolean statements containing OR or
AND are not supported"), but the search_issues repair prompt listed them as
valid syntax and told the agent to keep explicit tokens. Without an agent
provider, queries went to the API unchecked.
Move the CLI's query sanitizer into toolkit-core as rewriteSearchQuery and
run it in search_issues after the optional agent repair. It strips AND,
turns same-key OR into in-lists, and throws a UserInputError with
alternatives for anything it can't rewrite. The CLI keeps a thin wrapper
for its stderr warning and ValidationError.
A new issueSearch option covers the most common failure, is:X OR is:Y.
is: rejects in-lists, but the status and substatus filters it maps to
accept them, so it rewrites to status:[...] or substatus:[...]. Substatus
lists must share one parent status, because the endpoint adds a status
filter for the first substatus only. It also unwraps parentheses that
reduce to plain terms, since issue search silently matches nothing for
grouped queries.
Fix the agent prompt and tool description to match.
Co-Authored-By: Burak Yigit Kaya <126780+BYK@users.noreply.github.com>
Co-Authored-By: Andrew Liu <andrew.liu@sentry.io>
|
The latest updates on your projects. Learn more about Vercel for GitHub. 1 Skipped Deployment
|
(is:unresolved OR is:resolved) OR is:ignored threw, because the paren group became status:[...] first and the is: merge only accepted is: operands. Accept status/substatus in-lists as operands when the merged field matches.
BYK
approved these changes
Oct 26, 2026
substatus:[new] OR substatus:[archived_forever] failed the is: merge and fell through to the generic same-key merge, producing a cross-parent substatus list the endpoint silently narrows to the first value's status. In issue search, route every OR group with an is:, status:, or substatus: operand through the status merge only.
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 35e618e. Configure here.
Substatus:[new] OR substatus:[archived_forever] skipped the parent-status check because the guard matched keys exactly, then the case-insensitive generic merge combined them. Lowercase keys in the guard to match.
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.

search_issueswas sending AND/OR to the issues endpoint, which rejects them withBoolean statements containing "OR" or "AND" are not supported in this search. That's the topsearch_issuesfailure insentry/mcp-server: about 93K a week across many users, mostlyis:X OR is:Y.Two things in MCP let them through:
search-issues/config.ts) listedAND, OR, NOTas valid syntax and told the agent to keep explicit tokens.What changes
@sentry/toolkit-core/search-query.rewriteSearchQueryreturns{ query, notes }and throwsSearchQueryError. Each product decides how to report: the CLI wrapper (cli/src/lib/search-query.ts) keeps its stderr warning andValidationError, and MCP throwsUserInputError. CLI behavior is unchanged except one error line, which now readskey:[val1,val2]instead of--query "key:[val1,val2]".search_issuesruns it after the optional agent repair, right beforelistIssues, so it covers the no-provider path too. When it rewrites a query, the result says so and shows the query it ran. Queries it can't rewrite fail with aUserInputErrorthat lists alternatives, before any API call.issueSearchoption (MCP only for now):is:A OR is:Bbecomesstatus:[A,B]orsubstatus:[A,B].is:rejects in-lists, but the status and substatus filters it maps to accept them.expand_substatus_query_values). Sois:ongoing OR is:archived_foreveris still rejected.is:unresolved (is:regressed OR is:escalating)becomesis:unresolved substatus:[regressed,escalating].status:, andsubstatus:forms instead.Checked against the live API (sentry org,
juniorproject, 14d,X-Hits):status:[unresolved,resolved]returned 165, which is 159 (is:unresolved) + 6 (is:resolved).substatus:[new,ongoing]returned 159, which is 53 (is:new) + 106 (is:ongoing).substatus:[ongoing,archived_forever]returned only unresolved issues, and[archived_forever,ongoing]returned none. That's the first-substatus behavior the parent-status check guards against.(is:unresolved)returned[]andNOT is:resolvedreturned[](NOT is searched as free text), both with a 200. That's why the prompt now says!instead of NOT, and why parentheses get unwrapped.is:[unresolved,resolved]returned a 400:"in" syntax invalid for "is" search.Reviewing the move
Git shows the core file as new, because the CLI path still holds the wrapper. To see only what changed in the moved code:
Not in this PR
issue listcould opt intoissueSearch. I left it off to keep CLI behavior unchanged.get_sentry_resourceis task 4.1 of docs(openspec): Propose a shared Sentry API layer for the CLI and MCP #1669.Checks
pnpm run tscandpnpm run lintpass.toolkit-core(356),mcp-core(1833), and the CLI search-query, issue, log, span, and replay tests (532).test/lib+test/commandsrun has 6 failures in filesystem-permission tests (completions, upgrade lock, code scanner, file-changes). The completions and upgrade-lock failures also happen onmainin this sandbox, so they look environment-specific.via @BYK.
--
View Junior Session [Sentry]