Skip to content

stream: reject writes during WritableStream close - #67058

Open
mcollina wants to merge 1 commit into
nodejs:mainfrom
mcollina:webstreams-write-after-close
Open

mcollina wants to merge 1 commit into
nodejs:mainfrom
mcollina:webstreams-write-after-close

Conversation

@mcollina

Copy link
Copy Markdown
Member

WritableStreamDefaultControllerProcessClose clears the controller algorithms while the stream is still 'writable', before the sink close settles. A write in that window reaches the cleared size algorithm and fails the internal assertion in writableStreamDefaultControllerGetChunkSize, which crashes the process instead of rejecting the write:

const ws = new WritableStream({ close() { return new Promise(() => {}); } });
const writer = ws.getWriter();
writer.close();
setImmediate(() => writer.write('x'));
// Error [ERR_INTERNAL_ASSERTION]: This is caused by either a bug in Node.js ...

The same happens when writing to a TransformStream whose flush() is pending. This affects v26.5.1 as well as main.

#57280 handled the 'closed' case (#57272, whatwg/streams#1341). The spec still asserts that the state is not 'writable' there, so the close-in-flight window is a gap in the spec too. This also accepts that state, so the write continues to the closing check and is rejected with a TypeError, as it is once the stream has closed.

Tests are added to test-whatwg-writablestream-close.js for both cases; they fail with the assertion on main.

Refs: #57272
Refs: whatwg/streams#1341

🤖 Generated with Claude Code

https://claude.ai/code/session_01Sfj4nCwaLmXB1NxA7sEJfi

WritableStreamDefaultControllerProcessClose clears the controller
algorithms while the stream is still 'writable', before the sink close
settles. A write in that window, such as writer.write() after
writer.close() while the sink's close() or a TransformStream's flush()
is pending, reached the cleared size algorithm and failed an internal
assertion instead of being rejected as closing. Accept that state in
writableStreamDefaultControllerGetChunkSize so the write is rejected
with a TypeError, as it is once the stream has closed.

Refs: nodejs#57272
Refs: whatwg/streams#1341
Signed-off-by: Matteo Collina <hello@matteocollina.com>
@nodejs-github-bot nodejs-github-bot added needs-ci PRs that need a full CI run. web streams Issues and PRs related to the Web Streams API. labels Oct 27, 2026
@codecov

codecov Bot commented Oct 27, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 90.65%. Comparing base (29bd740) to head (199d95b).
⚠️ Report is 214 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main   #67058      +/-   ##
==========================================
+ Coverage   90.47%   90.65%   +0.18%     
==========================================
  Files         791      797       +6     
  Lines      277245   278270    +1025     
  Branches    53310    53503     +193     
==========================================
+ Hits       250834   252277    +1443     
+ Misses      16811    16385     -426     
- Partials     9600     9608       +8     
Files with missing lines Coverage Δ
lib/internal/webstreams/writablestream.js 99.52% <100.00%> (+<0.01%) ⬆️

... and 135 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

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

Labels

needs-ci PRs that need a full CI run. web streams Issues and PRs related to the Web Streams API.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants