Skip to content

Fail fast on unbalanced quotes in plain-text queries - #153

Merged
shouze merged 2 commits into
fix/regex-api-term-quotesfrom
fix/plain-text-quote-validation
Aug 23, 2026
Merged

Fail fast on unbalanced quotes in plain-text queries#153
shouze merged 2 commits into
fix/regex-api-term-quotesfrom
fix/plain-text-quote-validation

Conversation

@shouze

@shouze shouze commented Aug 23, 2026

Copy link
Copy Markdown
Contributor

What does this PR do?

Closes #149.

Plain-text (non-regex) queries with raw double quotes could silently produce false positives (GitHub strips balanced quotes and treats adjacent punctuation as separate terms) or an opaque 422 ERROR_TYPE_QUERY_PARSING_FATAL from the API when the quote count was odd.

validateQuoteBalance() in src/regex.ts now detects an odd number of unescaped double quotes in a plain-text query before any network call, and github-code-search.ts exits early with an actionable message that includes a corrected example using GitHub's documented double-escaping syntax (shell and GitHub). Regex /pattern/ queries are unaffected, they are validated separately by buildApiQuery/extractApiTerm (see #147). Balanced-quote queries, including legitimate exact-phrase queries like "feature flag", keep working unchanged.

How did you verify your code works?

  • Added unit tests in src/regex.test.ts covering balanced, unbalanced, escaped, and regex-bypass cases.
  • Ran the full suite, lint, format check and knip; all green.
  • Built the binary and confirmed the reported unbalanced-quote query now fails locally with a clear message instead of the previous raw GitHub 422, and that a legitimate two-quote phrase query still works unchanged.

@shouze shouze changed the title Fail fast on unbalanced quotes in plain-text queries (#149) Fail fast on unbalanced quotes in plain-text queries Aug 23, 2026
@shouze
shouze force-pushed the fix/plain-text-quote-validation branch from cc070de to af9a0ca Compare August 23, 2026 13:58
@github-actions

Copy link
Copy Markdown

Coverage after merging fix/plain-text-quote-validation into fix/regex-api-term-quotes will be

95.91%

Coverage Report
FileStmtsBranchesFuncsLinesUncovered Lines
src
   aggregate.ts100%100%100%100%
   api-utils.ts93.20%100%93.75%93.13%101–103, 65, 73, 86–87, 91–92
   api.ts94.57%100%100%93.89%319–323, 384, 401, 63–69
   cache.ts94.67%100%100%94.29%139–141, 39
   completions.ts99.42%100%100%99.37%270
   group.ts99.50%100%97.44%100%
   output.ts99.29%100%95.65%99.61%80
   regex.ts99.37%100%100%99.32%320
   render.ts89.87%100%89.47%89.89%167, 191–196, 198–200, 202–203, 254–255, 276, 463–464, 487–489, 555–559, 571–572, 577–584, 586–594, 596–597
   upgrade.ts88.38%100%94.44%87.89%128, 131, 133, 153, 167–168, 188–195, 198–204, 209, 214, 250–253
src/render
   filter-match.ts97.44%100%92.31%100%
   filter.ts100%100%100%100%
   highlight.ts96.63%100%90.40%99.31%284–285
   rows.ts97.58%100%100%97.44%168, 54–55
   selection.ts100%100%100%100%
   summary.ts100%100%100%100%
   team-pick.ts100%100%100%100%

@shouze
shouze marked this pull request as ready for review August 23, 2026 14:06
Copilot AI lite review requested due to automatic review settings August 23, 2026 14:06

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR adds local validation to fail fast on plain-text GitHub code-search queries that contain an odd number of unescaped double quotes, preventing opaque GitHub API 422 ERROR_TYPE_QUERY_PARSING_FATAL failures and reducing confusing false-positive behavior.

Changes:

  • Added validateQuoteBalance() in src/regex.ts to detect unbalanced (unescaped) " in non-regex queries and return an actionable error message.
  • Wired quote-balance validation into the CLI (github-code-search.ts) so the program exits before any API call.
  • Added unit tests in src/regex.test.ts covering balanced/unbalanced/escaped inputs and a regex-bypass case.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

File Description
src/regex.ts Introduces quote-balance validation logic for plain-text queries.
src/regex.test.ts Adds unit tests for the new quote-balance validation behavior.
github-code-search.ts Calls the validator early and exits with a user-facing error message on failure.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread src/regex.test.ts Outdated
Comment thread src/regex.ts
Plain-text (non-regex) queries with an odd number of unescaped double quotes
were sent straight to the GitHub API, which rejects them with an opaque
422 ERROR_TYPE_QUERY_PARSING_FATAL. validateQuoteBalance() now detects this
locally before any network call and exits with an actionable message,
including a corrected example using GitHub's documented double-escaping
syntax (shell + GitHub).

Balanced-quote queries (including legitimate exact-phrase queries like
"feature flag") and regex /pattern/ queries are unaffected — the latter are
already validated separately by buildApiQuery/extractApiTerm.

Closes #149
@shouze
shouze force-pushed the fix/plain-text-quote-validation branch from af9a0ca to aae0acb Compare August 23, 2026 14:26
@github-actions

Copy link
Copy Markdown

Coverage after merging fix/plain-text-quote-validation into fix/regex-api-term-quotes will be

95.91%

Coverage Report
FileStmtsBranchesFuncsLinesUncovered Lines
src
   aggregate.ts100%100%100%100%
   api-utils.ts93.20%100%93.75%93.13%101–103, 65, 73, 86–87, 91–92
   api.ts94.57%100%100%93.89%319–323, 384, 401, 63–69
   cache.ts94.67%100%100%94.29%139–141, 39
   completions.ts99.42%100%100%99.37%270
   group.ts99.50%100%97.44%100%
   output.ts99.29%100%95.65%99.61%80
   regex.ts99.37%100%100%99.32%320
   render.ts89.87%100%89.47%89.89%167, 191–196, 198–200, 202–203, 254–255, 276, 463–464, 487–489, 555–559, 571–572, 577–584, 586–594, 596–597
   upgrade.ts88.38%100%94.44%87.89%128, 131, 133, 153, 167–168, 188–195, 198–204, 209, 214, 250–253
src/render
   filter-match.ts97.44%100%92.31%100%
   filter.ts100%100%100%100%
   highlight.ts96.63%100%90.40%99.31%284–285
   rows.ts97.58%100%100%97.44%168, 54–55
   selection.ts100%100%100%100%
   summary.ts100%100%100%100%
   team-pick.ts100%100%100%100%

1 similar comment
@github-actions

Copy link
Copy Markdown

Coverage after merging fix/plain-text-quote-validation into fix/regex-api-term-quotes will be

95.91%

Coverage Report
FileStmtsBranchesFuncsLinesUncovered Lines
src
   aggregate.ts100%100%100%100%
   api-utils.ts93.20%100%93.75%93.13%101–103, 65, 73, 86–87, 91–92
   api.ts94.57%100%100%93.89%319–323, 384, 401, 63–69
   cache.ts94.67%100%100%94.29%139–141, 39
   completions.ts99.42%100%100%99.37%270
   group.ts99.50%100%97.44%100%
   output.ts99.29%100%95.65%99.61%80
   regex.ts99.37%100%100%99.32%320
   render.ts89.87%100%89.47%89.89%167, 191–196, 198–200, 202–203, 254–255, 276, 463–464, 487–489, 555–559, 571–572, 577–584, 586–594, 596–597
   upgrade.ts88.38%100%94.44%87.89%128, 131, 133, 153, 167–168, 188–195, 198–204, 209, 214, 250–253
src/render
   filter-match.ts97.44%100%92.31%100%
   filter.ts100%100%100%100%
   highlight.ts96.63%100%90.40%99.31%284–285
   rows.ts97.58%100%100%97.44%168, 54–55
   selection.ts100%100%100%100%
   summary.ts100%100%100%100%
   team-pick.ts100%100%100%100%

…le query

Addresses Copilot review feedback: validateQuoteBalance() previously
returned null for any query containing a /pattern/ regex token (via
isRegexQuery), skipping validation for everything else in the query. A
mixed query like 'filename:package.json /regex/ "oops' could still reach
the GitHub API with an unbalanced stray quote outside the token, hitting
the same opaque 422 ERROR_TYPE_QUERY_PARSING_FATAL issue #149 was meant to
prevent entirely.

Now only the /pattern/ token itself is excluded from the quote-balance
check (its quotes are handled separately by buildApiQuery/extractApiTerm),
while the rest of the query (qualifiers, free text) is still validated.

See #153 (comment)
@github-actions

Copy link
Copy Markdown

Coverage after merging fix/plain-text-quote-validation into fix/regex-api-term-quotes will be

95.91%

Coverage Report
FileStmtsBranchesFuncsLinesUncovered Lines
src
   aggregate.ts100%100%100%100%
   api-utils.ts93.20%100%93.75%93.13%101–103, 65, 73, 86–87, 91–92
   api.ts94.57%100%100%93.89%319–323, 384, 401, 63–69
   cache.ts94.67%100%100%94.29%139–141, 39
   completions.ts99.42%100%100%99.37%270
   group.ts99.50%100%97.44%100%
   output.ts99.29%100%95.65%99.61%80
   regex.ts99.39%100%100%99.34%329
   render.ts89.87%100%89.47%89.89%167, 191–196, 198–200, 202–203, 254–255, 276, 463–464, 487–489, 555–559, 571–572, 577–584, 586–594, 596–597
   upgrade.ts88.38%100%94.44%87.89%128, 131, 133, 153, 167–168, 188–195, 198–204, 209, 214, 250–253
src/render
   filter-match.ts97.44%100%92.31%100%
   filter.ts100%100%100%100%
   highlight.ts96.63%100%90.40%99.31%284–285
   rows.ts97.58%100%100%97.44%168, 54–55
   selection.ts100%100%100%100%
   summary.ts100%100%100%100%
   team-pick.ts100%100%100%100%

@shouze
shouze merged commit 44305b6 into main Aug 23, 2026
5 checks passed
@shouze
shouze deleted the fix/plain-text-quote-validation branch August 23, 2026 15:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Plain text queries with raw double quotes silently produce wrong results or an opaque 422

2 participants