Bound sandbox-gh-wrapper.cjs's stdin read so it can't hang forever - #6
Merged
Conversation
Reported from real use: `gh pr create ... --body "$(cat <<'BODY' ... BODY)"` run inside a ccserver sandbox hung. readStdin() had no timeout at all and relied entirely on process.stdin.isTTY to decide whether to skip it -- but that's not a hard guarantee: whatever invokes `gh` inside the sandbox may hand this process a non-TTY stdin (e.g. an fd shared with a longer-lived shell/pty) that was never going to send EOF on its own, and the vast majority of gh invocations don't read stdin at all (input comes via flags). readStdin() now gives up after 200ms if nothing arrives at all, and once real data starts flowing, allows a generous-but-bounded 2s inactivity window rather than waiting indefinitely for the stream to close. Added server/ws/sandbox-gh-wrapper.test.js as a regression test: spawns the wrapper against a real broker + fake gh with stdin left open and never written to, and asserts it still completes in well under a second. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YNFA5BLgmig7RswZypScjX
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.
Summary
gh pr create --base develop --title "..." --body "$(cat <<'BODY' ...multi-line markdown... BODY)"hung inside a ccserver sandbox. Switching to--body-file <path>worked around it.sandbox-gh-wrapper.cjs'sreadStdin()(added in Scope gh CLI through the git broker instead of disabling it #5) and found a real, independent bug: it has no timeout at all and relies entirely onprocess.stdin.isTTYto decide whether to skip reading. That's not a hard guarantee -- whatever invokesghinside the sandbox may hand this process a non-TTY stdin (e.g. an fd shared with a longer-lived shell/pty) that was never going to send EOF on its own, and the vast majority of gh invocations don't read stdin at all (title/body/etc. come in as flags).--body-fileshould still go through the same unconditionalreadStdin()call, which is a bit inconsistent with that being the fix that worked -- the original hang could equally have been a Bash-tool/pty issue with typing a large heredoc, unrelated to this code). Fixing this regardless since it's a real latent hang risk in code I own here.Fix
readStdin()now:Test plan
npm test-- 66 tests passing (63 existing + 3 new)server/ws/sandbox-gh-wrapper.test.js: spawns the real wrapper against a real broker + fakegh, with stdin left open and never written to -- completes in ~300ms instead of hanging (this is the exact regression scenario)--body-file -) still being forwarded correctly -- the timeout doesn't break legitimate piped input🤖 Generated with Claude Code
https://claude.ai/code/session_01YNFA5BLgmig7RswZypScjX