Skip to content

EPIC: Fix regex search coverage and double-quote handling in code search queries #146

Description

@shouze

Context and problem

github-code-search produces drastically incomplete or incorrect results in two scenarios related to double quote handling in code search queries.

Reproduction 1: regex mode, missing results

Command: github-code-search '/"react":\s*"[~^]?[0-9]/' --org fulll

Observed: only 2 results shown in the TUI.

Expected: a result set comparable to the GitHub web search for /"react":\s*"[~^]?[0-9]/ org:fulll (dozens of package.json files).

Reproduction 2: plain text mode, false positives

Command: github-code-search '"react": ' --org fulll

Observed: 666 files / 1000 matches, with many false positives (react-native.config.js, plain react imports, markdown docs).

Expected: only files literally containing "react": (typically package.json files).

Reproduction 3: plain text mode, opaque 422 error

Command: github-code-search '"react": "' --org fulll

Observed: error: GitHub API error 422: ERROR_TYPE_QUERY_PARSING_FATAL unable to parse query!

This still happens even when trying to escape the quotes at the shell level, because the shell consumes the backslash before the program ever receives it. The argv actually received by the process ends up identical in both attempts: "react": " (3 raw unbalanced quotes).

Evidence collected via direct API calls (bypassing the CLI)

Query sent to /search/code HTTP total_count Observation
react org:fulll 200 20288 Term currently extracted for the regex in reproduction 1, massive noise
react org:fulll filename:package.json 200 148 Still noisy (react-dom, @emotion/react, and similar)
"react": org:fulll (2 quotes, reproduction 2) 200 19712 GitHub strips the quotes, colon becomes a separate term, same false positives as observed
"react": " org:fulll (3 quotes, reproduction 3) 422 n/a ERROR_TYPE_QUERY_PARSING_FATAL, odd number of unescaped quotes
"react" org:fulll (single word in quotes, a naive regex-hint) 200 20288 Identical to plain react, quoting a single word has zero filtering effect on GitHub's side
escaped literal "react": " org:fulll (correct GitHub escaping) 200 126 Every fragment and segment matches exactly "react": ", zero noise
same escaped literal plus filename:package.json 200 117 Same precision, narrower scope

Root cause analysis

  1. src/regex.ts (extractApiTerm and longestLiteralSequence) breaks the literal sequence on any double quote character. For the regex in reproduction 1 the API term sent today is only react, too broad for the right files to ever surface within GitHub's 1000 result best match cap.
  2. src/aggregate.ts only applies the local regex filter to TextMatch.fragment, the truncated excerpt returned by the API, even though src/api.ts already downloads the full file content to resolve line numbers and then discards it.
  3. There is no local validation of quote balance in plain text queries: GitHub silently strips balanced quotes (false positives) and rejects unbalanced quotes with an opaque 422.
  4. Current documentation does not explain the double escaping layer required (shell and GitHub), and the existing regex-hint example wrapping a single word in quotes is misleading since it has no filtering effect.
  5. Related regression from PR 133: src/api.ts no longer derives the matched segment text from the fragment when GitHub omits it, which can cause matchedText to be missing in JSON output.

Solution and architecture principles

  • Do not guess user intent. A plain text query with balanced quotes such as a legitimate exact phrase must keep working unchanged, no silent auto-escaping that would change the meaning of an already valid query.
  • Fail fast on the client side, never a raw 422. If a plain text query contains an odd number of unescaped quotes, the CLI must stop before calling the GitHub API, with an actionable message and a corrected example.
  • Respect the existing layering documented in AGENTS.md: term extraction and escaping stay pure functions in src/regex.ts with no I/O. File content already downloaded in src/api.ts must be propagated through src/types.ts rather than duplicated or re-fetched.
  • No new network calls. The file content used for the local regex fallback filter is content already fetched during line number resolution.
  • Add a regression test for each sub-issue before applying the fix, per the repository bug fixing instructions.

Sub-issues

This epic is broken down into 5 sub-issues, linked below in execution order.

  1. Regex API term extraction discards quotes, causing regex queries to lose most matches
  2. Local regex filter should not depend solely on the possibly truncated API fragment
  3. Plain text queries with raw double quotes silently produce wrong results or an opaque 422
  4. Documentation is incorrect or incomplete regarding quote escaping and regex-hint effectiveness
  5. Restore the missing matched text derivation regression from PR 133

Suggested execution order: 1 and 3 in parallel (disjoint files, highest priority), 2 in parallel with 1 and 3 as hardening, 4 last since it documents the final behavior of 1 and 3, 5 independent and lowest risk.

Acceptance criteria

  • The command from reproduction 1 returns a result count of the same order of magnitude as the equivalent GitHub web search, dozens rather than 2.
  • The command from reproduction 2 no longer returns obvious false positives.
  • The command from reproduction 3 fails locally with a clear message before any API call, and never surfaces a raw 422 to the user.
  • regex-hint is documented with an example that has a real, verifiable effect.
  • No regression on existing queries that already worked correctly, covered by the existing test suite.

Definition of done

  • bun test passes, including new regression tests for each sub-issue
  • bun run lint passes with zero errors
  • bun run format:check passes with no diff
  • bun run knip reports no unused exports or imports
  • bun run build.ts compiles successfully
  • Manual validation of the 3 reproductions above using the compiled binary
  • docs/usage/search-syntax.md, README.md and docs/reference/cli-options.md updated
  • CHANGELOG.md updated and a patch release published after merge

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

bugSomething isn't workingepic

Type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions