Skip to content

stream: fix ERR_INVALID_STATE when cancelling Readable.toWeb() - #62773

Open
richardscarrott wants to merge 1 commit into
nodejs:mainfrom
richardscarrott:fix/readable-to-web-cancel-race
Open

stream: fix ERR_INVALID_STATE when cancelling Readable.toWeb()#62773
richardscarrott wants to merge 1 commit into
nodejs:mainfrom
richardscarrott:fix/readable-to-web-cancel-race

Conversation

@richardscarrott

Copy link
Copy Markdown

When a web ReadableStream returned by Readable.toWeb() is cancelled while the underlying Readable is actively producing data, a pending onData callback can still fire after the controller has been closed and attempt to enqueue a chunk, throwing ERR_INVALID_STATE.

Check wasCanceled in the onData handler and return early to avoid calling controller.enqueue() on a closed controller.

Refs: #54205

@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 Apr 16, 2026
@codecov

codecov Bot commented Apr 16, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 90.17%. Comparing base (fd5b135) to head (c0fe52d).
⚠️ Report is 402 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main   #62773      +/-   ##
==========================================
+ Coverage   90.12%   90.17%   +0.05%     
==========================================
  Files         752      771      +19     
  Lines      252325   264910   +12585     
  Branches    47456    50310    +2854     
==========================================
+ Hits       227407   238894   +11487     
- Misses      16217    16981     +764     
- Partials     8701     9035     +334     
Files with missing lines Coverage Δ
lib/internal/webstreams/adapters.js 88.04% <100.00%> (+1.43%) ⬆️

... and 260 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.

@efekrskl

efekrskl commented Jul 17, 2026

Copy link
Copy Markdown
Member

Thank you for your contribution @richardscarrott!

Could you please fix the linting errors?

@smoores-dev

Copy link
Copy Markdown

Howdy folks! I think we're running into this as well — @richardscarrott if you don't have time to take this over the finish line, happy to take it over and fix the linting errors!

@richardscarrott

Copy link
Copy Markdown
Author

@smoores-dev @efekrskl soz, forgot about this. I have some time tomorrow to fix this up.

@richardscarrott
richardscarrott force-pushed the fix/readable-to-web-cancel-race branch from 96e546b to 93b1db6 Compare August 23, 2026 10:13
@richardscarrott

Copy link
Copy Markdown
Author

Rebased onto main and fixed the lint error.

Worth flagging for re-review: #62394 rewrote newReadableStreamFromStreamReadable after this PR was opened, so the patch needed porting — the onData logic now lives in an inline 'data' listener. I confirmed the race is still present on current main; without the guard, test-stream-readable-to-web-termination.js fails with:

TypeError [ERR_INVALID_STATE]: Invalid state: Controller is already closed
    at ReadableStreamDefaultController.enqueue (node:internal/webstreams/readablestream:1189:13)
    at Readable.onData (node:internal/webstreams/adapters:547:18)
    at flow (node:internal/streams/readable:1319:53)
    at resume_ (node:internal/streams/readable:1295:3)

Note this is the enqueue path, distinct from the close path in #54205 (which #54206 already fixed) — hence Refs: rather than Fixes:. Upstream's rewritten test file is preserved as-is with the new case appended.

@meixg your approval predates the rebase, so this likely needs another look.

@meixg meixg added request-ci Add this label to start a Jenkins CI on a PR. Only starts once the PR has an approving review. author ready PRs with CI started, the required approvals, and no outstanding review comments. labels Sep 6, 2026
@github-actions github-actions Bot removed the request-ci Add this label to start a Jenkins CI on a PR. Only starts once the PR has an approving review. label Sep 6, 2026
@nodejs-github-bot

Copy link
Copy Markdown
Collaborator

@meixg meixg added the commit-queue PRs queued for automated landing through the Commit Queue. label Sep 6, 2026
@nodejs-github-bot nodejs-github-bot added commit-queue-failed PRs whose Commit Queue landing failed and need manual intervention before retrying. and removed commit-queue PRs queued for automated landing through the Commit Queue. labels Sep 6, 2026
@nodejs-github-bot

This comment was marked as resolved.

MikeMcC399

This comment was marked as resolved.

@panva panva removed author ready PRs with CI started, the required approvals, and no outstanding review comments. commit-queue-failed PRs whose Commit Queue landing failed and need manual intervention before retrying. labels Sep 7, 2026
When a web ReadableStream returned by Readable.toWeb() is cancelled
while the underlying Readable is actively producing data, a pending
onData callback can still fire after the controller has been closed
and attempt to enqueue a chunk, throwing ERR_INVALID_STATE.

Check wasCanceled in the onData handler and return early to avoid
calling controller.enqueue() on a closed controller.

Refs: nodejs#54205
Signed-off-by: Richard Scarrott <riscarrott@googlemail.com>
@richardscarrott
richardscarrott force-pushed the fix/readable-to-web-cancel-race branch from 93b1db6 to c0fe52d Compare September 7, 2026 12:29
@richardscarrott

Copy link
Copy Markdown
Author

Added the missing Signed-off-by trailer (thanks @MikeMcC399) — message-only amend, so the tree is identical to the previously reviewed commit. lint-commit-message is green now.

Could a collaborator start a fresh CI run and re-add the author ready label? The force-push cleared it (@meixg's approval still stands).

@MikeMcC399 MikeMcC399 added the author ready PRs with CI started, the required approvals, and no outstanding review comments. label Sep 7, 2026
@MikeMcC399

MikeMcC399 commented Sep 7, 2026

Copy link
Copy Markdown
Contributor

Added the missing Signed-off-by trailer (thanks @MikeMcC399) — message-only amend, so the tree is identical to the previously reviewed commit. lint-commit-message is green now.

Thanks for fixing the trailer!

Could a collaborator start a fresh CI run and re-add the author ready label? The force-push cleared it (@meixg's approval still stands).

@panva is re-running the GitHub Actions CI. I have put back the author ready PRs with CI started, the required approvals, and no outstanding review comments. label, although I don't believe that's a critical point.

It's going to need another Jenkins CI triggered, however there is currently some work being done to fix a flaky test, so I'll let @panva continue looking after your PR. I'm not sure if @meixg will need to reapprove or not. We'll see!

@panva panva left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

@panva panva added the request-ci Add this label to start a Jenkins CI on a PR. Only starts once the PR has an approving review. label Sep 7, 2026
@github-actions github-actions Bot removed the request-ci Add this label to start a Jenkins CI on a PR. Only starts once the PR has an approving review. label Sep 7, 2026
@nodejs-github-bot

Copy link
Copy Markdown
Collaborator

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

Labels

author ready PRs with CI started, the required approvals, and no outstanding review comments. 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.

8 participants