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
- 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.
- 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.
- 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.
- 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.
- 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.
- Regex API term extraction discards quotes, causing regex queries to lose most matches
- Local regex filter should not depend solely on the possibly truncated API fragment
- Plain text queries with raw double quotes silently produce wrong results or an opaque 422
- Documentation is incorrect or incomplete regarding quote escaping and regex-hint effectiveness
- 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
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)
Root cause analysis
Solution and architecture principles
Sub-issues
This epic is broken down into 5 sub-issues, linked below in execution order.
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
Definition of done