Skip to content

fix(cli): handle stdout/stderr stream errors in execFileUtf8Tail#100850

Merged
vincentkoc merged 4 commits into
openclaw:mainfrom
cxbAsDev:fix/logs-cli-runtime-stream-errors
Jul 6, 2026
Merged

fix(cli): handle stdout/stderr stream errors in execFileUtf8Tail#100850
vincentkoc merged 4 commits into
openclaw:mainfrom
cxbAsDev:fix/logs-cli-runtime-stream-errors

Conversation

@cxbAsDev

@cxbAsDev cxbAsDev commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

What Problem This Solves

execFileUtf8Tail in src/cli/logs-cli.runtime.ts spawns a subprocess and reads stdout/stderr, but only attaches "data" listeners. If either stream emits an "error" event, it is unhandled and can crash the CLI log-tail command.

Why This Change Was Made

Added "error" listeners to child.stdout and child.stderr that resolve the promise with a failed result, reusing the existing settled guard. The shared resolveWithError helper also replaces the duplicate child-process error handler.

User Impact

openclaw logs and other CLI flows that tail subprocess output now fail gracefully with an error message instead of crashing on stream errors.

Evidence

Regression tests:

pnpm test src/cli/logs-cli.runtime.test.ts
Test Files  1 passed (1)
     Tests  2 passed (2)

Real behavior proof:

node_modules/.bin/tsx scripts/proof/logs-cli-runtime-stream-errors.mts
=== Proof: logs-cli runtime execFileUtf8Tail stream error handling ===

Result: code=1, stderr=stdout read failed

PASS: stream errors were caught and execFileUtf8Tail returned a failed result.

@openclaw-barnacle openclaw-barnacle Bot added cli CLI command changes size: S labels Jul 6, 2026
@clawsweeper

clawsweeper Bot commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs maintainer review before merge. Reviewed July 6, 2026, 11:06 AM ET / 15:06 UTC.

Summary
The PR adds stdout/stderr stream error handling to execFileUtf8Tail, focused Vitest coverage, and a CLI logs runtime proof script.

PR surface: Source +5, Tests +50, Other +60. Total +115 across 3 files.

Reproducibility: yes. from source inspection: readSystemdJournalFallback reaches execFileUtf8Tail, current main attaches only data listeners to stdout/stderr, and a Node EventEmitter error with no listener throws. I did not run the PR tests in this read-only review.

Review metrics: none identified.

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

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

Rank-up moves:

  • none.

Next step before merge

  • [P2] No repair job is needed because this active focused PR has sufficient proof, green exact-head checks in the live PR view, and no concrete review findings.

Security
Cleared: Cleared: the diff changes a CLI runtime helper plus tests/proof script only; it does not alter dependencies, workflows, permissions, secret handling, or package metadata.

Review details

Best possible solution:

Land the focused helper-level stream error handling after normal maintainer review; keep adjacent subprocess helper hardening PRs separate unless maintainers decide to batch them.

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

Yes from source inspection: readSystemdJournalFallback reaches execFileUtf8Tail, current main attaches only data listeners to stdout/stderr, and a Node EventEmitter error with no listener throws. I did not run the PR tests in this read-only review.

Is this the best way to solve the issue?

Yes. Handling the error in execFileUtf8Tail, which owns the child stdout/stderr pipes, is the narrowest maintainable fix; sibling subprocess helpers already handle output stream errors at that boundary.

AGENTS.md: found and applied where relevant.

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

Label changes

Label justifications:

  • P2: The PR fixes a focused CLI crash-hardening gap in openclaw logs with limited blast radius.
  • rating: 🐚 platinum hermit: Overall readiness is 🐚 platinum hermit; proof is 🦞 diamond lobster and patch quality is 🐚 platinum hermit.
  • status: 👀 ready for maintainer look: ClawSweeper has no concrete contributor-facing blocker left for this PR. Sufficient (terminal): Sufficient: the PR body includes terminal output from a proof script that injects stdout/stderr stream errors, and the exact-head Real behavior proof check succeeded.
  • proof: sufficient: Contributor real behavior proof is sufficient. Sufficient: the PR body includes terminal output from a proof script that injects stdout/stderr stream errors, and the exact-head Real behavior proof check succeeded.
Evidence reviewed

PR surface:

Source +5, Tests +50, Other +60. Total +115 across 3 files.

View PR surface stats
Area Files Added Removed Net
Source 1 7 2 +5
Tests 1 50 0 +50
Docs 0 0 0 0
Config 0 0 0 0
Generated 0 0 0 0
Other 1 60 0 +60
Total 3 117 2 +115

What I checked:

  • Current main helper lacks stream error listeners: Current main buffers child stdout/stderr and handles child error/close, but it does not attach error listeners to the stdout or stderr streams themselves. (src/cli/logs-cli.runtime.ts:28, fbf574ad9db2)
  • Affected user-facing entry point: readSystemdJournalFallback reaches runtime.execFileUtf8Tail("journalctl", ...), so the helper is on the openclaw logs --follow Linux journal fallback path. (src/cli/logs-cli.ts:314, fbf574ad9db2)
  • PR wires the missing handlers: The PR adds a shared error resolver and attaches it to child.stdout, child.stderr, and the child process error event. (src/cli/logs-cli.runtime.ts:59, f23ed142e5a2)
  • Regression coverage: The PR adds focused tests for stdout and stderr stream error events resolving to failed results rather than becoming unhandled errors. (src/cli/logs-cli.runtime.test.ts:16, f23ed142e5a2)
  • Sibling subprocess invariant: A sibling process helper already attaches stdout/stderr stream error listeners, supporting this as a subprocess-boundary concern rather than a caller-level fix. (src/process/exec.ts:617, fbf574ad9db2)
  • Node EventEmitter behavior check: A Node 24.18.0 check confirmed an emitted error event with no listener throws, matching the reported crash mode.

Likely related people:

  • vincentkoc: Authored the merged logs-follow journal fallback that introduced execFileUtf8Tail, later merged adjacent stream-error hardening work, and has recent history around subprocess stream handling. (role: introduced behavior and adjacent owner; confidence: high; commits: 6e3b3183dd85, 67b539ec7b61, 72830619e61b; files: src/cli/logs-cli.runtime.ts, src/cli/logs-cli.ts, src/agents/utils/child-process.ts)
  • anyech: Authored the merged logs-follow retry and journal cursor work around the same fallback path. (role: recent area contributor; confidence: medium; commits: bd5bf4820ab3, fb9bb08a980e; files: src/cli/logs-cli.ts)
  • cxbAsDev: Beyond this PR, authored recently merged stdout/stderr stream-error hardening changes for other child-process helpers. (role: adjacent stream-error hardening contributor; confidence: medium; commits: 73448fd8bfeb, f66f582654e1; files: src/agents/utils/child-process.ts, src/agents/sandbox/docker.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 (2 earlier review cycles)
  • reviewed 2026-07-06T11:51:25.494Z sha e73d615 :: needs real behavior proof before merge. :: none
  • reviewed 2026-07-06T14:18:57.048Z sha 79dcc46 :: needs maintainer review before merge. :: none

@clawsweeper clawsweeper Bot added rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. P2 Normal backlog priority with limited blast radius. labels Jul 6, 2026
@openclaw-barnacle openclaw-barnacle Bot added the scripts Repository scripts label Jul 6, 2026
@cxbAsDev
cxbAsDev force-pushed the fix/logs-cli-runtime-stream-errors branch from 3d0f7fc to 79dcc46 Compare July 6, 2026 14:04
@clawsweeper clawsweeper Bot added proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. and removed rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. labels Jul 6, 2026
@openclaw-barnacle openclaw-barnacle Bot removed the scripts Repository scripts label Jul 6, 2026
@vincentkoc vincentkoc self-assigned this Jul 6, 2026
@vincentkoc

Copy link
Copy Markdown
Member

Maintainer repair is land-ready on exact head 6e68bb958cf61115f39c2aabe05f2d16685aec91:

  • kept the contributor's valid stdout/stderr stream-error handling
  • terminate the live journalctl child on output pipe failure so it cannot hold the CLI open
  • preserve partial stdout and the existing spawn-error/normal-close contracts
  • replaced duplicate tests with table-driven stdout/stderr lifecycle coverage and removed the standalone proof script
  • focused runtime + CLI tests: 40/40 passed
  • formatting, diff check, and test-temp guard passed
  • Node 26 live process probe observed the child close via SIGTERM
  • fresh gpt-5.5 high-reasoning autoreview: clean, confidence 0.86
  • Blacksmith Testbox check:changed: tbx_01kwvzc16cep8kgrxby4ye0147, run 28801495849, passed
  • exact-head GitHub Actions CI 28801822672: passed, including QA Smoke CI
  • OpenGrep 28801822508 attempt 2: passed after the first installer-only network failure
  • repo-native scripts/pr prepare-run 100850: passed with exact head parity

No docs or changelog change is required for this narrow internal CLI reliability fix.

@vincentkoc
vincentkoc merged commit 9606fe4 into openclaw:main Jul 6, 2026
97 of 100 checks passed
@vincentkoc

Copy link
Copy Markdown
Member

Merged via squash.

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

* fix(cli): handle stdout/stderr stream errors in execFileUtf8Tail

* chore(proof): add real behavior proof for logs-cli runtime stream errors

* chore(proof): fix promise executor lint in logs-cli proof

* fix(cli): terminate log tail children on stream errors

---------

Co-authored-by: Vincent Koc <[email protected]>
giodl73-repo pushed a commit to giodl73-repo/openclaw that referenced this pull request Jul 8, 2026
…nclaw#100850)

* fix(cli): handle stdout/stderr stream errors in execFileUtf8Tail

* chore(proof): add real behavior proof for logs-cli runtime stream errors

* chore(proof): fix promise executor lint in logs-cli proof

* fix(cli): terminate log tail children on stream errors

---------

Co-authored-by: Vincent Koc <[email protected]>
@cxbAsDev
cxbAsDev deleted the fix/logs-cli-runtime-stream-errors branch July 15, 2026 03:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cli CLI command changes P2 Normal backlog priority with limited blast radius. proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🐚 platinum hermit Good normal PR readiness with ordinary 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