Skip to content

fix(agents): handle ripgrep stdout/stderr stream errors in grep tool#101014

Merged
steipete merged 6 commits into
openclaw:mainfrom
cxbAsDev:fix/grep-tool-stream-errors
Jul 6, 2026
Merged

fix(agents): handle ripgrep stdout/stderr stream errors in grep tool#101014
steipete merged 6 commits into
openclaw:mainfrom
cxbAsDev:fix/grep-tool-stream-errors

Conversation

@cxbAsDev

@cxbAsDev cxbAsDev commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

What Problem This Solves

The built-in grep tool owned a piped ripgrep child but did not handle stdout or stderr stream failures. Node treats an unhandled error event as process-fatal, and readline removes its input-error listener when the interface closes, so a pipe failure could crash the agent runtime or escape after cleanup.

Why This Change Was Made

One lifecycle-owned stream-error helper now terminates ripgrep, closes readline, removes the abort listener, and rejects the tool promise exactly once. Both readline's re-emitted input error and the direct stdout guard remain attached; the direct guard is required after readline closes. The implementation mirrors the landed find-tool invariant without adding a new shared abstraction.

Duplicate proof scaffolding and the root changelog edit were removed. Test kill state is modeled without mutating Node's readonly child-process property.

User Impact

Grep tool calls fail with a contextual stdout/stderr error instead of crashing the Gateway, hanging, or returning incomplete matches.

Evidence

  • Current head 612a686a5c18d31abfd5811e6c21fe9255cfd807; focused head 66d6b728a001f23075bf82ff6e8244d09c7e7c3d on sanitized public-network AWS Crabbox cbx_81807643f51a with no Tailscale or instance profile:
    • run run_f0ff41fe6048: pnpm test src/agents/sessions/tools/grep.stream-errors.test.ts — 3/3 passed.
    • run run_678bc00cab3e: real managed ripgrep searched a fixture successfully, then real stdout and stderr pipe failures terminated their children while the parent stayed alive.
  • Fresh Codex AutoReview: clean, confidence 0.83.
  • Current runtime/test blobs match the live-proven blobs after the base-only rebase.
  • Exact-head hosted CI is running on the post-QA-fix base.

The stream contract was checked against Node's official EventEmitter documentation and readline implementation.

@cxbAsDev

cxbAsDev commented Jul 6, 2026

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

@clawsweeper

clawsweeper Bot commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event repository_dispatch).
Result: the existing ClawSweeper review comment will be edited in place when the review finishes.

@clawsweeper

clawsweeper Bot commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs maintainer review before merge. Reviewed July 6, 2026, 5:00 PM ET / 21:00 UTC.

Summary
The PR adds stdout/stderr stream-error handling to the grep tool and a regression test covering clean rejection and child termination on stream failures.

PR surface: Source +13, Tests +78. Total +91 across 2 files.

Reproducibility: yes. source inspection gives a high-confidence reproduction path: current main and v2026.6.11 attach no raw stdout/stderr error listeners in the grep spawn path, and Node throws unhandled error events. I did not execute a failing current-main run because this review was read-only.

Review metrics: none identified.

Stored data model
Persistent data-model change detected: serialized state: src/agents/sessions/tools/grep.stream-errors.test.ts, serialized state: src/agents/sessions/tools/grep.ts, unknown-data-model-change: src/agents/sessions/tools/grep.stream-errors.test.ts. Confirm migration or upgrade compatibility proof before merge.

Merge readiness
Overall: 🦞 diamond lobster
Proof: 🦞 diamond lobster
Patch quality: 🦞 diamond lobster
Result: ready for maintainer review.

Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch.

Risk before merge

  • [P1] GitHub reports the PR as mergeable but behind current main, so final landing should refresh against current main and rely on exact-head CI rather than the older base SHA.

Maintainer options:

  1. Decide the mitigation before merge
    Land the focused grep stream-error fix after the normal base refresh and exact-head CI, keeping the implementation local to the grep child-process lifecycle and the regression test focused on stream failures.
  2. Pause or close
    Do not merge this PR until maintainers decide whether the risk is worth taking.

Next step before merge

  • No ClawSweeper repair lane is needed because the prior review blocker is fixed and no current blocking finding remains; maintainers should refresh and land through normal exact-head CI if they accept the fix.

Security
Cleared: The diff only changes grep stream-error handling and a focused test; it adds no dependencies, workflows, package-resolution changes, secrets handling, or new permissions.

Review details

Best possible solution:

Land the focused grep stream-error fix after the normal base refresh and exact-head CI, keeping the implementation local to the grep child-process lifecycle and the regression test focused on stream failures.

Do we have a high-confidence way to reproduce the issue?

Yes, source inspection gives a high-confidence reproduction path: current main and v2026.6.11 attach no raw stdout/stderr error listeners in the grep spawn path, and Node throws unhandled error events. I did not execute a failing current-main run because this review was read-only.

Is this the best way to solve the issue?

Yes. The fix belongs at the grep-owned child-process/readline boundary; a shared abstraction is not required for this small patch, and the shape matches the merged find-tool invariant.

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning high; reviewed against c7295e417d5d.

Label changes

Label changes:

  • add rating: 🦞 diamond lobster: Overall readiness is 🦞 diamond lobster; proof is 🦞 diamond lobster and patch quality is 🦞 diamond lobster.
  • add status: 👀 ready for maintainer look: ClawSweeper has no concrete contributor-facing blocker left for this PR. Sufficient (terminal): The PR body includes terminal proof from a sanitized AWS Crabbox run where focused tests passed and a real managed ripgrep path rejected stdout/stderr pipe failures while the parent stayed alive.
  • remove rating: 🦐 gold shrimp: Current PR rating is rating: 🦞 diamond lobster, so this older rating label is no longer current.
  • remove status: ⏳ waiting on author: Current PR status label is status: 👀 ready for maintainer look.

Label justifications:

  • P2: This is a focused agent-tool availability bug fix with limited blast radius and no current blocking review finding.
  • rating: 🦞 diamond lobster: Overall readiness is 🦞 diamond lobster; proof is 🦞 diamond lobster and patch quality is 🦞 diamond lobster.
  • status: 👀 ready for maintainer look: ClawSweeper has no concrete contributor-facing blocker left for this PR. Sufficient (terminal): The PR body includes terminal proof from a sanitized AWS Crabbox run where focused tests passed and a real managed ripgrep path rejected stdout/stderr pipe failures while the parent stayed alive.
  • proof: sufficient: Contributor real behavior proof is sufficient. The PR body includes terminal proof from a sanitized AWS Crabbox run where focused tests passed and a real managed ripgrep path rejected stdout/stderr pipe failures while the parent stayed alive.
Evidence reviewed

PR surface:

Source +13, Tests +78. Total +91 across 2 files.

View PR surface stats
Area Files Added Removed Net
Source 1 13 0 +13
Tests 1 78 0 +78
Docs 0 0 0 0
Config 0 0 0 0
Generated 0 0 0 0
Other 0 0 0 0
Total 2 91 0 +91

What I checked:

  • Repository policy read: Root and scoped agent policy were read and applied to require deep PR review, sibling tool comparison, dependency-contract inspection, and real behavior proof assessment. (AGENTS.md:1, c7295e417d5d)
  • Scoped agent policy read: The scoped agent guidance was read; it reinforced keeping focused agent tests lightweight and dependency-injected. (src/agents/AGENTS.md:1, c7295e417d5d)
  • Current main still lacks grep stream-error handlers: Current main spawns ripgrep, wraps stdout in readline, and reads stderr data, but has no stdout/stderr error listeners before the child close handler. (src/agents/sessions/tools/grep.ts:238, c7295e417d5d)
  • Latest release still lacks the fix: The latest release tag v2026.6.11 has the same grep spawn/readline/stderr path without raw stream-error handlers, so the PR is not obsolete or already shipped. (src/agents/sessions/tools/grep.ts:238, e085fa1a3ffd)
  • PR head adds one-shot grep stream failure cleanup: The current head adds a shared onStreamError path that stops ripgrep, closes readline, removes abort cleanup through cleanup(), and rejects with a stream-specific error only once. (src/agents/sessions/tools/grep.ts:266, 612a686a5c18)
  • Regression test covers the fixed behavior: The added test emits stdout and stderr errors, asserts rejection, checks child kill state through a safe getter-backed mock, and verifies stdout remains guarded after readline is closed by a stderr failure. (src/agents/sessions/tools/grep.stream-errors.test.ts:39, 612a686a5c18)

Likely related people:

  • Wynne668: Current-main blame and file history tie the grep spawn/readline implementation to commit 3dd5339. (role: introduced current grep tool surface; confidence: medium; commits: 3dd5339a535a; files: src/agents/sessions/tools/grep.ts, src/agents/sessions/tools/index.ts)
  • steipete: steipete is assigned on this PR, authored the latest cleanup commits on the PR head, and authored/merged the sibling find stream-failure fix that the grep patch mirrors. (role: recent adjacent owner and likely follow-up owner; confidence: high; commits: 976a52028a32, 6ad4b26adb14, 612a686a5c18; files: src/agents/sessions/tools/grep.ts, src/agents/sessions/tools/grep.stream-errors.test.ts, src/agents/sessions/tools/find.ts)
What the crustacean ranks mean
  • 🦀 challenger crab: rare, exceptional readiness with strong proof, clean implementation, and convincing validation.
  • 🦞 diamond lobster: very strong readiness with only minor maintainer review expected.
  • 🐚 platinum hermit: good normal PR, likely mergeable with ordinary maintainer review.
  • 🦐 gold shrimp: useful signal, but proof or patch confidence is still limited.
  • 🦪 silver shellfish: thin signal; proof, validation, or implementation needs work.
  • 🧂 unranked krab: not merge-ready because proof is missing/unusable or there are serious correctness or safety concerns.
  • 🌊 off-meta tidepool: rating does not apply to this item.

Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics.

How this review workflow works
  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.
Review history (3 earlier review cycles)
  • reviewed 2026-07-06T17:33:46.603Z sha f95aabf :: needs changes before merge. :: [P2] Terminate ripgrep after stream errors
  • reviewed 2026-07-06T18:44:10.938Z sha 5e0a530 :: needs changes before merge. :: [P2] Make the mock child reflect kill state
  • reviewed 2026-07-06T20:01:39.860Z sha a151dd8 :: needs changes before merge. :: [P2] Avoid assigning to readonly child state

@clawsweeper clawsweeper Bot added proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. P2 Normal backlog priority with limited blast radius. merge-risk: 🚨 availability 🚨 May cause crashes, hangs, restart loops, stalls, or process outages. labels Jul 6, 2026
@cxbAsDev
cxbAsDev force-pushed the fix/grep-tool-stream-errors branch 2 times, most recently from 423533a to 50f7e4f Compare July 6, 2026 17:59
@cxbAsDev

cxbAsDev commented Jul 6, 2026

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review\n\nUpdated the stdout/stderr stream-error handlers to call stopChild() before rejecting, and extended the regression tests to assert the child is killed.

@steipete steipete self-assigned this Jul 6, 2026
@cxbAsDev
cxbAsDev force-pushed the fix/grep-tool-stream-errors branch from 5e0a530 to 33d7013 Compare July 6, 2026 18:58
@cxbAsDev

cxbAsDev commented Jul 6, 2026

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review\n\nFixed the mock child so the kill spy mutates killed to true, matching the assertions. Test passes locally with pnpm test src/agents/sessions/tools/grep.stream-errors.test.ts.

@steipete
steipete requested a review from a team as a code owner July 6, 2026 19:20
@openclaw-barnacle openclaw-barnacle Bot added docs Improvements or additions to documentation channel: discord Channel integration: discord channel: telegram Channel integration: telegram app: android App: android app: web-ui App: web-ui gateway Gateway runtime extensions: qa-lab extensions: codex plugin: file-transfer and removed scripts Repository scripts labels Jul 6, 2026
@openclaw-barnacle openclaw-barnacle Bot added scripts Repository scripts size: S and removed size: XL labels Jul 6, 2026
@clawsweeper clawsweeper Bot removed the merge-risk: 🚨 availability 🚨 May cause crashes, hangs, restart loops, stalls, or process outages. label Jul 6, 2026
@steipete
steipete force-pushed the fix/grep-tool-stream-errors branch from a151dd8 to a1bcbaa Compare July 6, 2026 20:04
@openclaw-barnacle openclaw-barnacle Bot removed the scripts Repository scripts label Jul 6, 2026
@steipete
steipete force-pushed the fix/grep-tool-stream-errors branch 2 times, most recently from 98c7238 to 66d6b72 Compare July 6, 2026 20:28
@steipete
steipete force-pushed the fix/grep-tool-stream-errors branch from 66d6b72 to 612a686 Compare July 6, 2026 20:39
@clawsweeper clawsweeper Bot added rating: 🦞 diamond lobster Very strong PR readiness with only minor maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. and removed rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. labels Jul 6, 2026
@steipete

steipete commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

Land-ready maintainer proof

  • Refactored ripgrep stdout/stderr failures through one idempotent lifecycle owner while retaining the direct stdout guard required after readline closes.
  • Sanitized public-network AWS Crabbox cbx_81807643f51a, run run_f0ff41fe6048: pnpm test src/agents/sessions/tools/grep.stream-errors.test.ts — 3/3 passed.
  • Same lease, run run_678bc00cab3e: OpenClaw-managed ripgrep searched a real fixture; injected stdout and stderr failures terminated their children and left the parent healthy.
  • Fresh Codex AutoReview: clean, confidence 0.83.
  • Exact head 612a686a5c18d31abfd5811e6c21fe9255cfd807: CI release gate 28823516996 — success.
  • OPENCLAW_TESTBOX=1 scripts/pr prepare-run 101014 — passed; remote head and prepared head match.

Known proof gaps: none.

@steipete
steipete merged commit 0e0888a into openclaw:main Jul 6, 2026
191 of 237 checks passed
@steipete

steipete commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

Merged via squash.

github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request Jul 7, 2026
…penclaw#101014)

* fix(agents): handle ripgrep stdout/stderr stream errors in grep tool

* fix(agents): terminate ripgrep child on stdout/stderr stream errors

* test(agents): make mock child reflect kill state in grep stream-error test

* refactor(agents): harden grep stream cleanup

* refactor(agents): centralize grep stream failure cleanup

* test(agents): model grep child kill state safely

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
giodl73-repo pushed a commit to giodl73-repo/openclaw that referenced this pull request Jul 8, 2026
…penclaw#101014)

* fix(agents): handle ripgrep stdout/stderr stream errors in grep tool

* fix(agents): terminate ripgrep child on stdout/stderr stream errors

* test(agents): make mock child reflect kill state in grep stream-error test

* refactor(agents): harden grep stream cleanup

* refactor(agents): centralize grep stream failure cleanup

* test(agents): model grep child kill state safely

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
@cxbAsDev
cxbAsDev deleted the fix/grep-tool-stream-errors branch July 15, 2026 03:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agents Agent runtime and tooling P2 Normal backlog priority with limited blast radius. proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🦞 diamond lobster Very strong PR readiness with only minor maintainer review expected. size: S status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants