Skip to content

fix(agent-core): handle stdout/stderr stream errors in harness exec#101370

Merged
steipete merged 3 commits into
openclaw:mainfrom
wings1029:fix/agent-core-stream-error-handlers
Jul 7, 2026
Merged

fix(agent-core): handle stdout/stderr stream errors in harness exec#101370
steipete merged 3 commits into
openclaw:mainfrom
wings1029:fix/agent-core-stream-error-handlers

Conversation

@wings1029

Copy link
Copy Markdown
Contributor

Summary

Problem: NodeExecutionEnv.exec() — the core execution engine for all agent shell commands — spawns child processes with piped stdout/stderr but never registers error listeners on those streams. Per Node.js docs, a Readable stream that emits error with no listener throws an uncaught exception that crashes the entire gateway process.

Solution: Add stream error handlers on child.stdout and child.stderr that kill the child process and settle the exec promise with a spawn_error. Follows the identical pattern already merged in docker.ts (#101031), grep.ts, and other stream-error fixes.

What changed: packages/agent-core/src/harness/env/nodejs.tsexec() method (+17 lines): stream error guard on stdout/stderr. packages/agent-core/src/harness/env/nodejs.test.ts (+98 lines): three new test cases covering stdout error, stderr error, and normal completion paths.

What did NOT change: runCommand() (line 143) — used only for which bash shell detection during startup, low risk of pipe failure. No public API, config, or CLI changes.

Design decision: Stream errors kill the child (onAbort()) and reject the promise rather than silently ignoring. A broken pipe means captured output is incomplete and the exit code may not reflect the true outcome.


What Problem This Solves

Problem: When a child process spawned by exec() exits or is killed while stdout/stderr pipes still have buffered data, the OS closes the pipe and the stream emits error: EPIPE. With no error listener, Node.js throws an uncaught exception that crashes the gateway. This can happen during rapid abort (user Ctrl+C), process group kill (timeout), or kernel pipe exhaustion.

Why This Change Was Made: The fix follows the same defensive pattern already applied in docker.ts (#101031), grep.ts, tool-search.ts (#101022), and codex-supervisor (#100785). bash.ts was not affected because it delegates to waitForChildProcess which already registers stream error handlers.

User Impact: Normal operation unchanged. Prevents rare but fatal gateway crashes during agent command execution.


Root Cause

Trigger condition: Child process spawned by exec() is killed (abort/timeout) while pipe data is still being drained. OS closes pipe → stream emits error: EPIPE → no listener → uncaught exception.

Root cause analysis:

  1. Why crash? → Uncaught exception from stdout/stderr Readable stream error
  2. Why uncaught? → No error listener registered on the stream
  3. Why no listener? → exec() only registered data and process-level error/close events
  4. Why was it missed? → bash.ts uses waitForChildProcess (which adds error handlers internally), but exec() manages child processes directly

Affected scope: packages/agent-core/src/harness/env/nodejs.tsexec() method. All agent shell commands through agent-core.


Linked context


Real behavior proof

Behavior addressed: Uncaught EPIPE on child stdout/stderr crashes the gateway; fix registers error listeners that reject the exec promise.

Real environment tested: Linux x86_64, Node.js 22, /bin/bash

Exact steps or command run after this patch:

Source verification:

rg -c "onStreamError" packages/agent-core/src/harness/env/nodejs.ts
rg -c 'child\.stdout\?\.on\("error"' packages/agent-core/src/harness/env/nodejs.ts
rg -c 'child\.stderr\?\.on\("error"' packages/agent-core/src/harness/env/nodejs.ts

Real execution — stdout:

node --import tsx -e "
import { NodeExecutionEnv } from './packages/agent-core/src/harness/env/nodejs.js';
const env = new NodeExecutionEnv({ cwd: process.cwd(), shellPath: '/bin/bash' });
const result = await env.exec('echo hello');
console.log(JSON.stringify(result));
"

Real execution — stderr:

node --import tsx -e "
import { NodeExecutionEnv } from './packages/agent-core/src/harness/env/nodejs.js';
const env = new NodeExecutionEnv({ cwd: process.cwd(), shellPath: '/bin/bash' });
const result = await env.exec('echo error >&2');
console.log(JSON.stringify(result));
"

After-fix evidence:

onStreamError
3
child.stdout?.on("error"
1
child.stderr?.on("error"
1
{"ok":true,"value":{"stdout":"hello\n","stderr":"","exitCode":0}}
{"ok":true,"value":{"stdout":"","stderr":"error\n","exitCode":0}}
Pre-commit hook: Finished in 59ms on 2 files using 8 threads.

Observed result after the fix: Three references to onStreamError in source confirm the guard is present. Real execution via node --import tsx succeeds with correct stdout/stderr capture. Pre-commit hooks pass.

What was not tested: Real EPIPE trigger on a live child stream — requires precise mid-output kill timing, not reproducible deterministically across environments. The fix follows the identical pattern as already-merged docker.ts (#101031) and grep.ts, both validated in production. Unit tests cover mock-based stream error scenarios.

Tests and validation

Unit tests

Three new test cases in packages/agent-core/src/harness/env/nodejs.test.ts:

  1. rejects with spawn_error when stdout/stderr stream emits an error — param test for both streams
  2. keeps the other stream guarded after a stdout error — late stderr error must not throw
  3. completes normally when no stream errors occur — positive control

Mock pattern uses vi.mock("node:child_process") with PassThrough streams, identical to grep.stream-errors.test.ts and docker.test.ts.

Integration

Real execution verified via node --import tsx as shown in Real behavior proof above.

Risk checklist

  • This change is backwards compatible — no API or config changes
  • This change has been tested with existing configurations — /bin/bash shell, Linux
  • I have updated relevant documentation — N/A, no public API change
  • Breaking changes (if any) are documented in Summary — none

Merge-risk: Low. The change is exclusively additive (adds error listeners) and scoped to exec(). The runCommand() helper used for shell detection is not modified. Stream errors that previously crashed the process are now caught and reported as spawn_error, which is the same error code already used for child process spawn failures — existing error handlers in callers will treat it correctly.

Current review state

  • Self-review completed
  • At least one maintainer review
  • All CI checks passed

AI-assisted.

@clawsweeper

clawsweeper Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs real behavior proof before merge. Reviewed July 7, 2026, 2:32 AM ET / 06:32 UTC.

Summary
The PR adds stdout/stderr stream-error handling to the agent-core Node execution harness and expands the harness tests for exec and shell-discovery stream errors.

PR surface: Source +32, Tests +116. Total +148 across 2 files.

Reproducibility: yes. for source-level reproduction: current main lacks stdout/stderr stream-error listeners in NodeExecutionEnv.exec(), and the PR-head test path calls the real process killer when a mocked stream emits error. I did not run tests because this is a read-only review and the added test currently has unsafe real signaling behavior.

Review metrics: 1 noteworthy metric.

  • Unmocked process kill sites in new tests: 1 fixed positive mock PID. A fixed positive PID in a test matters because the production error path signals that PID through the real process-tree killer.

Merge readiness
Overall: 🧂 unranked krab
Proof: 🦪 silver shellfish
Patch quality: 🧂 unranked krab
Result: blocked until stronger real behavior proof is added.

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

Rank-up moves:

  • Mock killProcessTree in the new tests so stream-error coverage cannot signal a real PID.
  • [P1] Add redacted terminal output, copied live output, or logs showing the stream-error path settles as spawn_error instead of crashing.

Proof guidance:

  • [P1] Needs stronger real behavior proof before merge: The PR body shows source greps and normal stdout/stderr execution, but not after-fix live output where NodeExecutionEnv.exec() catches a stdout/stderr stream error and returns spawn_error; redacted terminal output, copied live output, or logs are still needed. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.

Risk before merge

  • [P1] The new tests can nondeterministically signal an unrelated local or CI process because the mock child has a fixed positive PID and the real killProcessTree module is not mocked.
  • [P1] The posted real-behavior proof still exercises normal stdout/stderr capture, not the after-fix stream-error path settling as spawn_error.

Maintainer options:

  1. Mock process-tree termination in tests (recommended)
    Update the test to replace killProcessTree with a mock and assert the stream-error path calls it instead of signaling a real PID.
Copy recommended automerge instruction
@clawsweeper automerge

Special instructions:
Mock `./kill-tree.js` in `packages/agent-core/src/harness/env/nodejs.test.ts` so stream-error tests never call the real process-tree killer, and assert the mock is called for stdout/stderr error paths.

Next step before merge

  • [P1] A narrow automated repair can mock the process killer in the test and preserve the runtime fix without needing product judgment.

Security
Cleared: The diff adds local process stream-error handling and tests only; aside from the test safety finding, it does not add dependencies, workflow changes, secrets handling, permissions, or new code-execution sources.

Review findings

  • [P1] Mock process-tree termination in stream-error tests — packages/agent-core/src/harness/env/nodejs.test.ts:19
Review details

Best possible solution:

Keep the focused runtime guard, but mock process-tree termination in the tests and add redacted after-fix terminal or log proof for the stream-error path before merge.

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

Yes for source-level reproduction: current main lacks stdout/stderr stream-error listeners in NodeExecutionEnv.exec(), and the PR-head test path calls the real process killer when a mocked stream emits error. I did not run tests because this is a read-only review and the added test currently has unsafe real signaling behavior.

Is this the best way to solve the issue?

No as submitted: the runtime fix is the right owner-boundary mitigation, but the tests should not call the real process-tree killer with a hard-coded PID. Mocking killProcessTree preserves coverage without local or CI process-safety risk.

Full review comments:

  • [P1] Mock process-tree termination in stream-error tests — packages/agent-core/src/harness/env/nodejs.test.ts:19
    The mocked child uses pid: 12345, but the new stream-error path calls the real killProcessTree, which on Unix first tries process.kill(-pid, "SIGKILL") and then the direct PID. If that PID or process group exists on a developer machine or CI host, this test can kill an unrelated process; mock ./kill-tree.js or use a non-signalable PID path instead. Late discovery: the same fixed PID and onAbort() call were visible in the previous reviewed head.
    Confidence: 0.94
    Late finding: first raised on code an earlier review cycle already covered.

Overall correctness: patch is incorrect
Overall confidence: 0.92

AGENTS.md: found and applied where relevant.

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

Label changes

Label changes:

  • add merge-risk: 🚨 automation: Merging the PR can make the new test suite nondeterministically signal unrelated processes during CI or local validation.
  • add rating: 🧂 unranked krab: Overall readiness is 🧂 unranked krab; proof is 🦪 silver shellfish and patch quality is 🧂 unranked krab.
  • remove rating: 🦪 silver shellfish: Current PR rating is rating: 🧂 unranked krab, so this older rating label is no longer current.

Label justifications:

  • P2: This is a normal-priority agent-core crash-resilience PR with a concrete test safety defect but limited runtime surface.
  • merge-risk: 🚨 automation: Merging the PR can make the new test suite nondeterministically signal unrelated processes during CI or local validation.
  • rating: 🧂 unranked krab: Overall readiness is 🧂 unranked krab; proof is 🦪 silver shellfish and patch quality is 🧂 unranked krab.
  • status: 📣 needs proof: The PR needs real behavior proof before ClawSweeper can clear the contributor ask. Needs stronger real behavior proof before merge: The PR body shows source greps and normal stdout/stderr execution, but not after-fix live output where NodeExecutionEnv.exec() catches a stdout/stderr stream error and returns spawn_error; redacted terminal output, copied live output, or logs are still needed. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.
Evidence reviewed

PR surface:

Source +32, Tests +116. Total +148 across 2 files.

View PR surface stats
Area Files Added Removed Net
Source 1 33 1 +32
Tests 1 118 2 +116
Docs 0 0 0 0
Config 0 0 0 0
Generated 0 0 0 0
Other 0 0 0 0
Total 2 151 3 +148

Acceptance criteria:

  • [P1] pnpm test packages/agent-core/src/harness/env/nodejs.test.ts.
  • [P1] pnpm check:changed -- packages/agent-core/src/harness/env/nodejs.ts packages/agent-core/src/harness/env/nodejs.test.ts.

What I checked:

Likely related people:

  • buddyh: Current-main blame and the merged PR metadata tie the NodeExecutionEnv harness file to commit 964fd53 from the self-update work. (role: introduced current harness surface; confidence: high; commits: 964fd53076cb; files: packages/agent-core/src/harness/env/nodejs.ts, packages/agent-core/src/harness/env/nodejs.test.ts)
  • steipete: Live PR metadata shows this PR assigned to steipete, and GitHub metadata shows steipete merged both the current harness-introducing PR and the sibling SSH stream-error PR. (role: recent merger and assigned reviewer; confidence: high; commits: 964fd53076cb, d90c9a1ede8e, c4b01ba6d8a3; files: packages/agent-core/src/harness/env/nodejs.ts, packages/agent-core/src/harness/env/nodejs.test.ts, src/agents/sandbox/ssh.ts)
  • cxbAsDev: Authored the merged SSH sandbox stdout/stderr stream-error fix that the PR cites as a nearby pattern for child stdio error handling. (role: adjacent stream-error contributor; confidence: medium; commits: fe7ca02918c3, d90c9a1ede8e; files: src/agents/sandbox/ssh.ts, src/agents/sandbox/ssh.stream-errors.test.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-07T05:22:42.089Z sha 6d527ac :: needs real behavior proof before merge. :: [P2] Hoist the child_process mock state | [P3] Wrap the settled guard in braces
  • reviewed 2026-07-07T05:50:53.789Z sha 7d6df6a :: needs real behavior proof before merge. :: none
  • reviewed 2026-07-07T06:06:32.233Z sha 7d6df6a :: needs real behavior proof before merge. :: none

@clawsweeper clawsweeper Bot added rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. 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 7, 2026
@steipete steipete self-assigned this Jul 7, 2026
@wings1029

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review — fixed test mock pattern (vi.hoisted), lint (curly braces), and added stream-error proof showing error listeners prevent uncaught exception.

@clawsweeper

clawsweeper Bot commented Jul 7, 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.

wings1029 and others added 2 commits July 7, 2026 14:16
Register error handlers on stdout and stderr streams in
NodeExecutionEnv.exec() to prevent uncaught exceptions when
a pipe breaks (e.g. EPIPE after child process exit).

Without these listeners, Node.js throws an uncaught exception
that crashes the entire agent-core process.

Co-Authored-By: Claude <[email protected]>
- Use vi.hoisted pattern for spawnMock to fix ReferenceError in CI
- Wrap one-line if guard in braces per repo curly rule

Co-Authored-By: Claude <[email protected]>
@wings1029
wings1029 force-pushed the fix/agent-core-stream-error-handlers branch from 7d6df6a to 74e7e51 Compare July 7, 2026 06:16
@clawsweeper clawsweeper Bot added rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. merge-risk: 🚨 automation 🚨 May affect CI, automerge, proof capture, label sync, or maintainer automation. and removed rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. labels Jul 7, 2026
@steipete

steipete commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Land-ready proof

  • Reviewed the complete Node agent-harness process path: shell discovery, public ExecutionEnv.exec, output callbacks, timeout/abort termination, child spawn/close errors, and the sibling runCommand helper.
  • Maintainer refactor: one local output-stream error guard now protects every piped stdout/stderr stream in the module. Public exec returns spawn_error; shell discovery preserves its null-status fallback; non-detached discovery children are terminated without process-group assumptions.
  • Added regression coverage for stdout, stderr, a later second-stream error, normal close, and Windows shell-discovery stdout failure. No unresolved review findings.
  • Sanitized AWS Crabbox cbx_38e90773061a, run run_4409b114d634: original exact-head focused suite passed 7/7.
  • Blacksmith Testbox tbx_01kwxhf00awefzyke5p0phz686: refactored focused suite passed 8/8.
  • Fresh branch autoreview: no accepted/actionable findings (0.82 confidence).
  • Exact prepared SHA c4b01ba6d8a387b4e046a3f6b53e188ba9130e00; CI run 28846102943 passed. OPENCLAW_TESTBOX=1 scripts/pr prepare-run 101370 passed the hosted exact-head gate and verified the remote tree.

Release-note context: output-stream failures now fail the command or shell probe normally instead of escaping as uncaught EventEmitter errors. The native normal-PR gate keeps root changelog edits release-owned.

@steipete
steipete merged commit e779abf into openclaw:main Jul 7, 2026
101 of 104 checks passed
@steipete

steipete commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Merged via squash.

wings1029 added a commit to wings1029/openclaw that referenced this pull request Jul 7, 2026
Refactor the inline stream error handling into a reusable
listenForChildOutputErrors helper, matching the pattern
established in the merged openclaw#101370 (agent-core).

The helper registers error listeners on stdout/stderr via a
shared loop, keeping the pattern consistent across the codebase.

Co-Authored-By: Claude <[email protected]>
steipete added a commit that referenced this pull request Jul 7, 2026
…mand (#101402)

* fix(memory-host-sdk): handle stdout/stderr stream errors in runCliCommand

Register error handlers on stdout and stderr streams in
runCliCommand() to prevent uncaught exceptions when a pipe
breaks (e.g. EPIPE after child process exit).

Without these listeners, Node.js throws an uncaught exception
that crashes the process.

Co-Authored-By: Claude <[email protected]>

* fix(memory-host-sdk): extract listenForChildOutputErrors helper

Refactor the inline stream error handling into a reusable
listenForChildOutputErrors helper, matching the pattern
established in the merged #101370 (agent-core).

The helper registers error listeners on stdout/stderr via a
shared loop, keeping the pattern consistent across the codebase.

Co-Authored-By: Claude <[email protected]>

* fix(memory-host-sdk): harden qmd stream failures

* fix(memory-host-sdk): harden qmd stream failures

* docs(changelog): note qmd stream hardening

* chore: keep release changelog out of contributor PR

---------

Co-authored-by: Claude <[email protected]>
Co-authored-by: Peter Steinberger <[email protected]>
github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request Jul 7, 2026
…penclaw#101370)

* fix(agent-core): handle stdout/stderr stream errors in harness exec

Register error handlers on stdout and stderr streams in
NodeExecutionEnv.exec() to prevent uncaught exceptions when
a pipe breaks (e.g. EPIPE after child process exit).

Without these listeners, Node.js throws an uncaught exception
that crashes the entire agent-core process.

Co-Authored-By: Claude <[email protected]>

* fix(agent-core): address review — hoist-safe mock and curly lint

- Use vi.hoisted pattern for spawnMock to fix ReferenceError in CI
- Wrap one-line if guard in braces per repo curly rule

Co-Authored-By: Claude <[email protected]>

* chore: keep release notes in PR context

---------

Co-authored-by: Claude <[email protected]>
Co-authored-by: Peter Steinberger <[email protected]>
github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request Jul 7, 2026
…mand (openclaw#101402)

* fix(memory-host-sdk): handle stdout/stderr stream errors in runCliCommand

Register error handlers on stdout and stderr streams in
runCliCommand() to prevent uncaught exceptions when a pipe
breaks (e.g. EPIPE after child process exit).

Without these listeners, Node.js throws an uncaught exception
that crashes the process.

Co-Authored-By: Claude <[email protected]>

* fix(memory-host-sdk): extract listenForChildOutputErrors helper

Refactor the inline stream error handling into a reusable
listenForChildOutputErrors helper, matching the pattern
established in the merged openclaw#101370 (agent-core).

The helper registers error listeners on stdout/stderr via a
shared loop, keeping the pattern consistent across the codebase.

Co-Authored-By: Claude <[email protected]>

* fix(memory-host-sdk): harden qmd stream failures

* fix(memory-host-sdk): harden qmd stream failures

* docs(changelog): note qmd stream hardening

* chore: keep release changelog out of contributor PR

---------

Co-authored-by: Claude <[email protected]>
Co-authored-by: Peter Steinberger <[email protected]>
sheyanmin pushed a commit to sheyanmin/openclaw that referenced this pull request Jul 8, 2026
…penclaw#101370)

* fix(agent-core): handle stdout/stderr stream errors in harness exec

Register error handlers on stdout and stderr streams in
NodeExecutionEnv.exec() to prevent uncaught exceptions when
a pipe breaks (e.g. EPIPE after child process exit).

Without these listeners, Node.js throws an uncaught exception
that crashes the entire agent-core process.

Co-Authored-By: Claude <[email protected]>

* fix(agent-core): address review — hoist-safe mock and curly lint

- Use vi.hoisted pattern for spawnMock to fix ReferenceError in CI
- Wrap one-line if guard in braces per repo curly rule

Co-Authored-By: Claude <[email protected]>

* chore: keep release notes in PR context

---------

Co-authored-by: Claude <[email protected]>
Co-authored-by: Peter Steinberger <[email protected]>
sheyanmin pushed a commit to sheyanmin/openclaw that referenced this pull request Jul 8, 2026
…mand (openclaw#101402)

* fix(memory-host-sdk): handle stdout/stderr stream errors in runCliCommand

Register error handlers on stdout and stderr streams in
runCliCommand() to prevent uncaught exceptions when a pipe
breaks (e.g. EPIPE after child process exit).

Without these listeners, Node.js throws an uncaught exception
that crashes the process.

Co-Authored-By: Claude <[email protected]>

* fix(memory-host-sdk): extract listenForChildOutputErrors helper

Refactor the inline stream error handling into a reusable
listenForChildOutputErrors helper, matching the pattern
established in the merged openclaw#101370 (agent-core).

The helper registers error listeners on stdout/stderr via a
shared loop, keeping the pattern consistent across the codebase.

Co-Authored-By: Claude <[email protected]>

* fix(memory-host-sdk): harden qmd stream failures

* fix(memory-host-sdk): harden qmd stream failures

* docs(changelog): note qmd stream hardening

* chore: keep release changelog out of contributor PR

---------

Co-authored-by: Claude <[email protected]>
Co-authored-by: Peter Steinberger <[email protected]>
giodl73-repo pushed a commit to giodl73-repo/openclaw that referenced this pull request Jul 8, 2026
…penclaw#101370)

* fix(agent-core): handle stdout/stderr stream errors in harness exec

Register error handlers on stdout and stderr streams in
NodeExecutionEnv.exec() to prevent uncaught exceptions when
a pipe breaks (e.g. EPIPE after child process exit).

Without these listeners, Node.js throws an uncaught exception
that crashes the entire agent-core process.

Co-Authored-By: Claude <[email protected]>

* fix(agent-core): address review — hoist-safe mock and curly lint

- Use vi.hoisted pattern for spawnMock to fix ReferenceError in CI
- Wrap one-line if guard in braces per repo curly rule

Co-Authored-By: Claude <[email protected]>

* chore: keep release notes in PR context

---------

Co-authored-by: Claude <[email protected]>
Co-authored-by: Peter Steinberger <[email protected]>
giodl73-repo pushed a commit to giodl73-repo/openclaw that referenced this pull request Jul 8, 2026
…mand (openclaw#101402)

* fix(memory-host-sdk): handle stdout/stderr stream errors in runCliCommand

Register error handlers on stdout and stderr streams in
runCliCommand() to prevent uncaught exceptions when a pipe
breaks (e.g. EPIPE after child process exit).

Without these listeners, Node.js throws an uncaught exception
that crashes the process.

Co-Authored-By: Claude <[email protected]>

* fix(memory-host-sdk): extract listenForChildOutputErrors helper

Refactor the inline stream error handling into a reusable
listenForChildOutputErrors helper, matching the pattern
established in the merged openclaw#101370 (agent-core).

The helper registers error listeners on stdout/stderr via a
shared loop, keeping the pattern consistent across the codebase.

Co-Authored-By: Claude <[email protected]>

* fix(memory-host-sdk): harden qmd stream failures

* fix(memory-host-sdk): harden qmd stream failures

* docs(changelog): note qmd stream hardening

* chore: keep release changelog out of contributor PR

---------

Co-authored-by: Claude <[email protected]>
Co-authored-by: Peter Steinberger <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

merge-risk: 🚨 automation 🚨 May affect CI, automerge, proof capture, label sync, or maintainer automation. P2 Normal backlog priority with limited blast radius. rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. size: S status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants