Add regression test for write-after-endInput race in ProcessTransport#229
Open
dumko2001 wants to merge 1 commit into
Open
Add regression test for write-after-endInput race in ProcessTransport#229dumko2001 wants to merge 1 commit into
dumko2001 wants to merge 1 commit into
Conversation
Reproduces the race described in anthropics#148: handleControlRequest() is launched fire-and-forget in readMessages(). When a result message arrives immediately after a control_request, endInput() closes stdin before the handler finishes its async work (e.g. canUseTool). The handler then calls write() on the ended stream. The catch block attempts a second write(), which becomes an unhandled rejection and crashes Node.js. The test fails against the current SDK (confirming the bug) and will pass once the fix is applied in ProcessTransport: private stdinEnded = false; endInput(): void { this.stdinEnded = true; if (this.processStdin) this.processStdin.end(); } write(data: string): void { if (this.stdinEnded) return; /* ... */ } Also includes the minimum test infrastructure (package.json, tsconfig.json, vitest.config.ts, .gitignore) needed to run the Vitest suite.
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
Regression test for #148. Reproduces the race where `handleControlRequest()` is launched fire-and-forget in `readMessages()`. When a `result` message arrives immediately after a `control_request`, `endInput()` closes stdin before the async handler finishes (e.g. `canUseTool` delay). The handler then calls `write()` on the ended stream — throwing `ERR_STREAM_WRITE_AFTER_END`. The `catch` block attempts a second `write()`, which becomes an unhandled rejection and crashes Node.js.
The test currently fails against the published SDK, confirming the bug. It will pass once the fix is applied.
Fix (for SDK source)
Silent drop is safe — after
endInput()the subprocess has already emitted itsresultand will not read further stdin.Changes
tests/process-transport-write-after-endinput.test.ts— regression test usingspawnClaudeCodeProcessto inject a controlled mock process, with acanUseTooldelay that guarantees the race firespackage.json,tsconfig.json,vitest.config.ts,.gitignore— minimum Vitest infrastructure (not present onmain)Closes #148