fix(shell): preserve output from fast-exiting commands - #46463
Merged
Merged
Conversation
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.
Why
Short-lived shell commands can finish successfully but return
(no output)instead of the bytes they printed. Bun resumes child stdout and stderr on exit; our Effect readers attach lazily, so output can be discarded before consumption starts.The failure also reproduces using the spawner implementation from before #46085. This is an older capture bug, not a reason to remove the post-exit drain deadline.
What Changes
PassThroughbuffers when setting up the handle, before the lazy Effect readers attach. This follows the capture pattern in Effect's Node spawner.The regression tests keep the process scope open, wait for a real child to exit, then read its output. Before the fix, separate and combined capture both return empty output in under 60 ms. Afterward, both retain stdout and stderr. A third case checks simultaneous 256 KiB outputs across backpressure.
Scope
Only child-output capture and its tests change. The shared one-second post-exit deadline, process-group termination, SIGKILL escalation, and MCP shutdown behavior remain intact. No public API or SDK cancellation-contract changes.
Verification
Run from package directories on macOS with Bun 1.3.14:
git diff --checkpass. Targeted lint has no errors and three pre-existing warnings.