Skip to content

fix(codex): suppress stdout/stderr stream errors in sandbox subprocesses#101777

Open
sunlit-deng wants to merge 9 commits into
openclaw:mainfrom
sunlit-deng:sunlit/fix/codex-processes-stream-errors-v2
Open

fix(codex): suppress stdout/stderr stream errors in sandbox subprocesses#101777
sunlit-deng wants to merge 9 commits into
openclaw:mainfrom
sunlit-deng:sunlit/fix/codex-processes-stream-errors-v2

Conversation

@sunlit-deng

@sunlit-deng sunlit-deng commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

What Problem This Solves

Fixes an issue where stdout or stderr pipe errors from Codex sandbox subprocesses could become unhandled Node stream errors and crash the exec-server WebSocket bridge.

Why This Change Was Made

Both sandbox subprocess owners now handle output-stream errors immediately. The process-RPC path keeps child close authoritative for exit/closed notifications, while the streaming HTTP path settles the response, terminates the helper, and defers backend finalization until child close.

User Impact

Codex sandbox process and streaming HTTP work no longer take down the bridge when an output pipe fails, and execution leases are still finalized exactly once after the child exits.

Evidence

  • Real process-RPC bridge: induced stdout/stderr pipe errors on the production startProcess() path; the WebSocket remained open, follow-up readProcess() succeeded, and process/closed arrived after child close.
  • Negative control: removing the production stdout error listener on the same bridge reproduced an uncaught EPIPE and exit code 1.
  • Real streaming HTTP boundary: ./node_modules/.bin/tsx proof-live.ts used the production response reader with a real child process and loopback WebSocket. The request settled on stream error, the socket stayed open, finalizeExec remained at zero before close, and ran exactly once after close.
  • Upstream Codex contract audit at openai/codex@61a44880a85d: codex-rs/exec-server/src/process.rs distinguishes Exited (process exit) from Closed (all output streams ended), while codex-rs/exec-server/src/local_process.rs emits Closed only after an exit code exists and the open-stream count reaches zero. The exec-server README documents the same process/exited then process/closed lifecycle. This confirms the branch's close-authoritative finalizeExec ordering: stream failure settles the request and terminates the helper, while backend finalization waits for child close.
  • Rebased and validated against openclaw/openclaw@bfd6f2efdc54.
  • Focused suite after rebase: 4 files and 43 tests passed with node scripts/run-vitest.mjs extensions/codex/src/app-server/sandbox-exec-server.pipe-survival.test.ts extensions/codex/src/app-server/sandbox-exec-server.http.test.ts extensions/codex/src/app-server/sandbox-exec-server.lifecycle.test.ts extensions/codex/src/app-server/sandbox-exec-server.test.ts.
$ ./node_modules/.bin/tsx proof-live.ts
stream-error rejected=true
stream-error message=sandbox http/request output stream error: EPIPE: induced stdout failure
stream-error socketOpenBeforeClose=true
stream-error finalizeBeforeClose=0
stream-error finalizeAfterClose=1
stream-error finalizeStatus={"status":"failed","exitCode":1,"timedOut":false,"token":"stream-error-token"}
malformed rejected=true
malformed socketOpenBeforeClose=true
malformed finalizeBeforeClose=0
malformed finalizeAfterClose=1
malformed finalizeStatus={"status":"failed","exitCode":1,"timedOut":false,"token":"malformed-token"}
proof-live.ts
import { spawn, type ChildProcessWithoutNullStreams } from "node:child_process";
import { once } from "node:events";
import { WebSocket, WebSocketServer } from "ws";
import { readStreamingSandboxHttpResponse } from "./extensions/codex/src/app-server/sandbox-exec-server/streaming-response.ts";

async function socketPair(): Promise<{
  client: WebSocket;
  server: WebSocket;
  wss: WebSocketServer;
}> {
  const wss = new WebSocketServer({ host: "127.0.0.1", port: 0 });
  await once(wss, "listening");
  const address = wss.address();
  if (typeof address === "string" || address === null) {
    throw new Error("unexpected websocket address");
  }
  const client = new WebSocket(`ws://127.0.0.1:${address.port}`);
  const [[server]] = await Promise.all([once(wss, "connection"), once(client, "open")]);
  return { client, server: server as WebSocket, wss };
}

async function closeSocketPair(pair: {
  client: WebSocket;
  server: WebSocket;
  wss: WebSocketServer;
}) {
  pair.client.close();
  pair.server.close();
  pair.wss.close();
}

async function waitForClose(child: ChildProcessWithoutNullStreams): Promise<void> {
  if (child.exitCode !== null || child.signalCode !== null) {
    return;
  }
  await once(child, "close");
}

async function proveStreamErrorCloseFinalizes(): Promise<void> {
  const pair = await socketPair();
  const finalizeCalls: unknown[] = [];
  const child = spawn(process.execPath, [
    "-e",
    "process.on('SIGTERM',function(){});setTimeout(function(){},300000)",
  ]);
  const requestPromise = readStreamingSandboxHttpResponse({
    child,
    execSpec: { finalizeToken: "stream-error-token" },
    finalizeExec: async (record) => {
      finalizeCalls.push(record);
    },
    requestId: "proof-stream-error",
    socket: pair.server,
  });

  child.stdout.emit("error", new Error("EPIPE: induced stdout failure"));
  const error = await requestPromise.catch((caught: unknown) => caught);
  console.log(`stream-error rejected=${error instanceof Error}`);
  console.log(`stream-error message=${error instanceof Error ? error.message : String(error)}`);
  console.log(`stream-error socketOpenBeforeClose=${pair.server.readyState === WebSocket.OPEN}`);
  console.log(`stream-error finalizeBeforeClose=${finalizeCalls.length}`);

  child.kill("SIGKILL");
  await waitForClose(child);
  await new Promise((resolve) => setImmediate(resolve));
  console.log(`stream-error finalizeAfterClose=${finalizeCalls.length}`);
  console.log(`stream-error finalizeStatus=${JSON.stringify(finalizeCalls[0])}`);
  await closeSocketPair(pair);
}

async function proveMalformedOutputCloseFinalizes(): Promise<void> {
  const pair = await socketPair();
  const finalizeCalls: unknown[] = [];
  const child = spawn(process.execPath, [
    "-e",
    "process.on('SIGTERM',function(){});process.stdout.write('not-json\\n');setTimeout(function(){},300000)",
  ]);
  const requestPromise = readStreamingSandboxHttpResponse({
    child,
    execSpec: { finalizeToken: "malformed-token" },
    finalizeExec: async (record) => {
      finalizeCalls.push(record);
    },
    requestId: "proof-malformed-output",
    socket: pair.server,
  });

  const error = await requestPromise.catch((caught: unknown) => caught);
  console.log(`malformed rejected=${error instanceof Error}`);
  console.log(`malformed socketOpenBeforeClose=${pair.server.readyState === WebSocket.OPEN}`);
  console.log(`malformed finalizeBeforeClose=${finalizeCalls.length}`);

  child.kill("SIGKILL");
  await waitForClose(child);
  await new Promise((resolve) => setImmediate(resolve));
  console.log(`malformed finalizeAfterClose=${finalizeCalls.length}`);
  console.log(`malformed finalizeStatus=${JSON.stringify(finalizeCalls[0])}`);
  await closeSocketPair(pair);
}

await proveStreamErrorCloseFinalizes();
await proveMalformedOutputCloseFinalizes();

AI-assisted: built with Codex

@clawsweeper

clawsweeper Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs maintainer review before merge. Reviewed July 26, 2026, 5:23 AM ET / 09:23 UTC.

ClawSweeper review

What this changes

The PR prevents stdout or stderr errors from Codex sandbox helper processes from crashing the exec-server bridge, while keeping streaming HTTP execution finalization owned by child close.

Merge readiness

⚠️ Ready for maintainer review - 3 items remain

This PR remains necessary: current main does not contain its sandbox exec-server stream-error handling, and the submitted real-process proof supports the intended fix. The branch is mergeable but behind main; refresh it against afb347c7f94fc8d7f40f1f3a54b192bb8d027408 and re-run the focused lifecycle proof before merge because this code relies on child-close ordering for lease finalization.

Priority: P1
Reviewed head: ff3d36df77de82a0d56d50a6be117134e414aab2

Review scores

Measure Result What it means
Overall readiness 🐚 platinum hermit (4/6) The branch presents a focused, well-tested reliability repair with strong live lifecycle evidence, but needs a current-main refresh before it is ready to land.
Proof confidence 🦞 diamond lobster (5/6) Sufficient (live_output): The PR body supplies redacted live output from a real spawned helper and loopback WebSocket showing stream-error settlement, an open socket before child close, zero pre-close finalizations, and exactly one post-close finalization; refresh that proof after rebasing onto current main.
Patch quality 🐚 platinum hermit (4/6) No actionable review findings were identified.

Verification

Check Result Evidence
Real behavior Verified Sufficient (live_output): The PR body supplies redacted live output from a real spawned helper and loopback WebSocket showing stream-error settlement, an open socket before child close, zero pre-close finalizations, and exactly one post-close finalization; refresh that proof after rebasing onto current main.
Evidence reviewed 5 items Changed process-RPC owner: The branch adds stdout and stderr error listeners immediately after the sandbox process is spawned, so stream-level EventEmitter errors cannot escape as unhandled errors while existing data and close handlers continue to own notifications.
Changed streaming response lifecycle: The branch moves streaming HTTP parsing into a dedicated reader, attaches stream-error handling, terminates a failed helper, and preserves child close as the point that finalizes the execution record.
Regression coverage: The added regression suite captures real spawned children and emits stdout/stderr errors on the production pipes for both sandbox subprocess owners.
Findings None None.
Security None None.

How this fits together

The bundled Codex plugin runs sandbox helper processes for process-RPC and streaming HTTP requests. Their stdout/stderr data drives WebSocket and HTTP responses, while the helper's close event releases the backend execution lease.

flowchart LR
  Request[Sandbox request] --> Helper[Sandbox helper process]
  Helper --> Streams[stdout and stderr streams]
  Streams --> Rpc[Process-RPC bridge]
  Streams --> Http[Streaming HTTP response]
  Streams --> Error[Stream error handling]
  Helper --> Close[Child close]
  Close --> Finalize[Execution lease finalization]
Loading

Before merge

  • Resolve merge risk (P1) - The branch is behind current main; its recorded proof was performed against bfd6f2efdc54, so rebasing could change the interaction between stream failure, helper termination, and close-authoritative lease finalization.
  • Resolve merge risk (P1) - The unavailable changed-node CI gate must be refreshed for the rebased head, but its failure alone is not evidence of a product regression.
  • Complete next step (P2) - No discrete code defect is supported on the current patch; the remaining merge action is a current-main rebase and lifecycle-proof refresh rather than an automated repair.
Agent review details

Security

None.

PR surface

Source +63, Tests +291. Total +354 across 5 files.

View PR surface stats
Area Files Added Removed Net
Source 4 214 151 +63
Tests 1 291 0 +291
Docs 0 0 0 0
Config 0 0 0 0
Generated 0 0 0 0
Other 0 0 0 0
Total 5 505 151 +354

Review metrics

None.

Merge-risk options

Maintainer options:

  1. Refresh the branch and lifecycle proof (recommended)
    Rebase onto current main, then verify that stdout/stderr failure settles the request without closing the bridge and that the execution lease finalizes exactly once after child close.
  2. Pause until refreshed evidence is available
    Do not merge the current behind-base head if the rebase changes the helper-close ordering or the focused current-head proof cannot be reproduced.

Technical review

Best possible solution:

Rebase this focused reliability fix onto current main, preserve child-close ownership of finalizeExec, and attach current-head focused test and redacted live-output proof before merging.

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

Yes, at source level: emitting an error on a child stdout or stderr stream without an error listener follows Node's fatal EventEmitter path, and the PR includes production-path regression coverage. The supplied real-process evidence also reports that the bridge stays open and finalization waits for child close.

Is this the best way to solve the issue?

Yes, subject to current-head refresh: handling errors at each subprocess owner and retaining child-close ownership of finalization is narrower than adding a bridge-wide fallback. The helper extraction also lets streaming HTTP distinguish request settlement from execution-lease release.

AGENTS.md: found and applied where relevant.

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

Labels

Label justifications:

  • P1: Unhandled helper output-stream errors can terminate the active Codex sandbox execution bridge.
  • merge-risk: 🚨 availability: This changes runtime child-process error and close ordering, which determines whether execution requests and their bridge remain available.
  • 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 (live_output): The PR body supplies redacted live output from a real spawned helper and loopback WebSocket showing stream-error settlement, an open socket before child close, zero pre-close finalizations, and exactly one post-close finalization; refresh that proof after rebasing onto current main.
  • proof: sufficient: Contributor real behavior proof is sufficient. The PR body supplies redacted live output from a real spawned helper and loopback WebSocket showing stream-error settlement, an open socket before child close, zero pre-close finalizations, and exactly one post-close finalization; refresh that proof after rebasing onto current main.

Evidence

What I checked:

  • Changed process-RPC owner: The branch adds stdout and stderr error listeners immediately after the sandbox process is spawned, so stream-level EventEmitter errors cannot escape as unhandled errors while existing data and close handlers continue to own notifications. (extensions/codex/src/app-server/sandbox-exec-server/processes.ts:127, ff3d36df77de)
  • Changed streaming response lifecycle: The branch moves streaming HTTP parsing into a dedicated reader, attaches stream-error handling, terminates a failed helper, and preserves child close as the point that finalizes the execution record. (extensions/codex/src/app-server/sandbox-exec-server/streaming-response.ts:17, ff3d36df77de)
  • Regression coverage: The added regression suite captures real spawned children and emits stdout/stderr errors on the production pipes for both sandbox subprocess owners. (extensions/codex/src/app-server/sandbox-exec-server.pipe-survival.test.ts:1, ff3d36df77de)
  • Recorded current review state: The latest ClawSweeper cycle found no discrete patch finding, but recorded that proof was run against bfd6f2efdc54 while this branch is behind current main afb347c7f94fc8d7f40f1f3a54b192bb8d027408; the three-way merge remains clean. (ff3d36df77de)
  • Related scope check: The similar Codex sandbox subprocess PR is closed unmerged, while the other related Codex PR covers node-cli-sessions rather than this sandbox exec-server path; neither replaces this work.

Likely related people:

  • sunlit-deng: Authored the nine commits that implement and repeatedly refine the current branch's process-RPC, streaming HTTP, lifecycle, and regression-test changes. (role: current patch author and recent contributor to this sandbox exec-server repair; confidence: medium; commits: d32c5cf75586, 34f41ac3eb04, 7ccd022bda91; files: extensions/codex/src/app-server/sandbox-exec-server/processes.ts, extensions/codex/src/app-server/sandbox-exec-server/http.ts, extensions/codex/src/app-server/sandbox-exec-server/streaming-response.ts)
  • wangmiao0668000666: Their related work examined the parallel node-cli-sessions child-process stream-error surface and explicitly distinguished it from this sandbox exec-server implementation. (role: adjacent Codex stream-error contributor; confidence: low; files: extensions/codex/src/node-cli-sessions.ts)

Rank-up moves

Optional improvements that raise the rating; they are not merge blockers.

  • Rebase onto current main and re-run the focused sandbox exec-server suite.
  • Attach redacted current-head live output confirming request settlement and one post-close finalization.

Rating scale

Score Internal tier Crab rank Meaning
6/6 S 🦀 challenger crab Exceptional readiness
5/6 A 🦞 diamond lobster Very strong readiness
4/6 B 🐚 platinum hermit Good normal PR; ordinary maintainer review
3/6 C 🦐 gold shrimp Useful, but confidence is limited
2/6 D 🦪 silver shellfish Proof or implementation needs work
1/6 F 🧂 unranked krab Not merge-ready
N/A NA 🌊 off-meta tidepool Rating does not apply

Overall follows the weaker of proof and patch quality.
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.

Workflow

  • 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.

History

Review history (53 earlier review cycles; latest 8 shown)
  • reviewed 2026-07-16T05:40:44.830Z sha 202b6b7 :: needs maintainer review before merge. :: none
  • reviewed 2026-07-17T00:01:16.104Z sha 6aaf52d :: needs maintainer review before merge. :: none
  • reviewed 2026-07-17T14:31:09.764Z sha a9385f3 :: needs maintainer review before merge. :: none
  • reviewed 2026-07-17T15:50:02.463Z sha 4a702c7 :: needs maintainer review before merge. :: none
  • reviewed 2026-07-19T01:42:19.032Z sha 3b75881 :: needs maintainer review before merge. :: none
  • reviewed 2026-07-26T00:02:53.750Z sha 4f3b3cf :: needs maintainer review before merge. :: none
  • reviewed 2026-07-26T00:34:38.676Z sha 792c42c :: needs maintainer review before merge. :: none
  • reviewed 2026-07-26T09:17:15.473Z sha ff3d36d :: needs maintainer review 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
@sunlit-deng

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

@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.

@sunlit-deng
sunlit-deng force-pushed the sunlit/fix/codex-processes-stream-errors-v2 branch from fa2b97f to af1cb33 Compare July 7, 2026 16:50
@sunlit-deng

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

@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.

@sunlit-deng

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

@clawsweeper clawsweeper Bot added proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. and removed 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. labels Jul 7, 2026
@sunlit-deng
sunlit-deng force-pushed the sunlit/fix/codex-processes-stream-errors-v2 branch from af1cb33 to e5324ca Compare July 7, 2026 23:37
@sunlit-deng

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

@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.

@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. and removed proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. labels Jul 7, 2026
@sunlit-deng

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

@clawsweeper

clawsweeper Bot commented Jul 8, 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 removed the rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. label Jul 8, 2026
@clawsweeper clawsweeper Bot added the status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. label Jul 12, 2026
@sunlit-deng

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

@clawsweeper

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

Re-review progress:

@sunlit-deng
sunlit-deng force-pushed the sunlit/fix/codex-processes-stream-errors-v2 branch from 2fefe95 to c4252b6 Compare July 13, 2026 02:44
@sunlit-deng

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

@clawsweeper

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

Re-review progress:

@sunlit-deng
sunlit-deng force-pushed the sunlit/fix/codex-processes-stream-errors-v2 branch from c4252b6 to 233a415 Compare July 13, 2026 03:48
@sunlit-deng

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

@clawsweeper

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

Re-review progress:

@clawsweeper clawsweeper Bot added proof: sufficient ClawSweeper judged the real behavior proof convincing. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. and removed status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. labels Jul 13, 2026
@sunlit-deng
sunlit-deng force-pushed the sunlit/fix/codex-processes-stream-errors-v2 branch from 233a415 to 28a0a3e Compare July 13, 2026 14:45
@clawsweeper clawsweeper Bot removed the rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. label Jul 13, 2026
@sunlit-deng

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

@clawsweeper

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

Re-review progress:

@sunlit-deng

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

@clawsweeper

clawsweeper Bot commented Jul 25, 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: when the review finishes, ClawSweeper will create the durable review comment if needed or update the existing comment in place.

Re-review progress:

…r stream errors

Route stdout/stderr error events through fail() inside
readStreamingSandboxHttpResponse so that a pre-header stream
error settles the request exactly once instead of hanging
indefinitely when the child process stays alive.

The outer no-op error listeners on the same streams (installed
before calling readStreamingSandboxHttpResponse) prevent the
EventEmitter from throwing before the settlement listener fires.
Separate stream-error request settlement from backend finalization so the
exec-server lease stays held while the helper process is still alive. The
close handler now owns finalizeExec for both child errors and stream errors,
preserving the close-authoritative lifecycle contract.
@sunlit-deng

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

@clawsweeper

clawsweeper Bot commented Jul 26, 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: when the review finishes, ClawSweeper will create the durable review comment if needed or update the existing comment in place.

Re-review progress:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

extensions: codex merge-risk: 🚨 availability 🚨 May cause crashes, hangs, restart loops, stalls, or process outages. P1 High-priority user-facing bug, regression, or broken workflow. proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. size: L 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.

1 participant