Conversation
`rgSearch` only parsed ripgrep's stdout and ignored its exit status, so any run that ended in an error (exit 2) with nothing collected — most commonly an invalid regex such as `(` — resolved to `[]`. The grep tool then told the model there were no matches, which is false: the search never ran. stderr was piped but never read, so the reason was lost too. Now stderr is drained concurrently and, when rg exits 2 with no matches collected, the search fails with rg's own message. Exit 2 with matches (partial read errors) still returns the matches. The grep tool includes the underlying cause in its `Search failed` error so the model can correct the pattern. Claude-Session: https://claude.ai/code/session_0134ujLF81GyXsCByibLcYsz
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.
The agent's
greptool answers "no matches" when ripgrep actually failed. Give it a pattern rg cannot compile, such as(, and the tool returns[]; the model concludes the code it was looking for does not exist and moves on. rg's own explanation (regex parse error ... unclosed group) is thrown away.Root cause
rgSearchinpackages/agent/src/services/fs.tsspawns rg with--json, parses match lines from stdout, and returns whatever it collected. It never inspects the exit status. ripgrep exits 1 for "no matches" and 2 for an error, so an invalid regex (exit 2, nothing on stdout) looks exactly like an empty search. stderr is piped but never read, so the reason is lost as well. The grep tool then collapses everyFsErrorinto a bareSearch failed for <pattern>, so even when a cause exists it is not shown.Fix
packages/agent/src/services/fs.ts: drain stderr concurrently (new Response(proc.stderr).text()), read rg's exit code fromproc.exited, and when it is 2 with no matches collected, fail with rg's stderr message. Exit 2 with matches (rg hit unreadable files but still matched) keeps returning the matches, so nothing that used to work is dropped.packages/agent/src/tools/fs.ts: include the underlying cause in the grep tool'sSearch failed for <pattern>: <cause>error so the model can fix its pattern..changeset/grep-invalid-regex-error.md: patch changeset for@magnitudedev/cli.Tests
packages/agent/src/services/fs.test.tsruns the real vendored rg binary throughFsLive.search(withresolveRgPathmocked topackages/ripgrep/bin/rg, since the embedded payload only resolves in a compiled build). Without the fix,search('(')succeeds with[]and the test fails onExit.isFailure; with the fix it fails with a message containingregex parse error. Two companion cases pin the unchanged behaviour: a valid pattern returns[{ file: 'a.txt', match: '1|hello world' }], and a non-matching pattern returns[]without failing.Testing conducted: regression test red on HEAD, green with the fix, red again with the exit-code guard disabled; full
bun testinpackages/agentshows the same 28 pre-existing failures with and without this change;tsc --noEmitinpackages/agentandpackages/acnreport no errors.Not changed
▚▚ Shipped by breken — self-healing software. This one's on us. breken.ai