Skip to content

events: fix weak listener retention overwrite - #64024

Open
aryansaves wants to merge 1 commit into
nodejs:mainfrom
aryansaves:fix-weak-listener-overwrite
Open

events: fix weak listener retention overwrite#64024
aryansaves wants to merge 1 commit into
nodejs:mainfrom
aryansaves:fix-weak-listener-overwrite

Conversation

@aryansaves

Copy link
Copy Markdown

The weakListeners() retention map in EventTarget stored a single listener per retainer key. Multiple addEventListener() calls sharing the same retainer (e.g. two listeners on one target using the same AbortSignal) silently evicted each other's strong reference, allowing the evicted listener to be garbage collected before its signal aborted, so only the most recently registered listener was ever actually removed on abort.

Changed the retention map to store a Set of listeners per retainer key instead of a single listener, and added matching cleanup in remove() so entries are released once their retainer's set is empty.

This also fixes the same class of bug in events.aborted() and the streams kWeakHandler usage, since both go through the same EventTarget.prototype.addEventListener() code path.

Fixes: #63954

@nodejs-github-bot nodejs-github-bot added the needs-ci PRs that need a full CI run. label Jun 20, 2026
@aryansaves

Copy link
Copy Markdown
Author

Friendly ping, could a collaborator approve CI when there's a moment , happy to address any review feedback.

@aryansaves

Copy link
Copy Markdown
Author

CI workflows are still awaiting approval, could someone approve the workflow run when there's a moment?

@trivikr trivikr added request-ci Add this label to start a Jenkins CI on a PR. events Issues and PRs related to the events subsystem / EventEmitter. author ready PRs that have at least one approval, no outstanding review comments, and a CI started. labels Aug 21, 2026
@github-actions github-actions Bot removed the request-ci Add this label to start a Jenkins CI on a PR. label Aug 21, 2026
@nodejs-github-bot

This comment was marked as outdated.

@aryansaves

Copy link
Copy Markdown
Author

CI ran but two jobs failed (node-test-commit, node-test-pull-request) I don't have Jenkins read access to check the logs, could a collaborator check ?

@nodejs-github-bot

This comment was marked as outdated.

@nodejs-github-bot

This comment was marked as outdated.

@nodejs-github-bot

This comment was marked as outdated.

@nodejs-github-bot

This comment was marked as outdated.

@nodejs-github-bot

This comment was marked as outdated.

@nodejs-github-bot

This comment was marked as outdated.

@nodejs-github-bot

This comment was marked as outdated.

@nodejs-github-bot

This comment was marked as outdated.

@nodejs-github-bot

This comment was marked as outdated.

@nodejs-github-bot

This comment was marked as resolved.

@trivikr

trivikr commented Aug 24, 2026

Copy link
Copy Markdown
Member

@aryansaves Can you please rebase?

Flaky tests are failing in test-build-sea which would have been either marked as flaky or fixed in recent commits.

The weakListeners() retention map in EventTarget stored a single
listener per retainer key. Multiple addEventListener() calls sharing
the same retainer (e.g. two listeners on one target using the same
AbortSignal) silently evicted each other's strong reference, allowing
the evicted listener to be garbage collected before its signal
aborted, so only the most recently registered listener was ever
actually removed on abort.

Changed the retention map to store a Set of listeners per retainer
key instead of a single listener, and added matching cleanup in
remove() so entries are released once their retainer's set is empty.

This also fixes the same class of bug in events.aborted() and the
streams kWeakHandler usage, since both go through the same
EventTarget.prototype.addEventListener() code path.

Fixes: nodejs#63954
Signed-off-by: aryan7905 <aryansrivastava354@gmail.com>
@aryansaves
aryansaves force-pushed the fix-weak-listener-overwrite branch from 142dfed to 225349a Compare August 25, 2026 04:22
@aryansaves

Copy link
Copy Markdown
Author

@trivikr rebase done, CI needs approval

@trivikr trivikr added the request-ci Add this label to start a Jenkins CI on a PR. label Aug 25, 2026
@github-actions github-actions Bot removed the request-ci Add this label to start a Jenkins CI on a PR. label Aug 25, 2026
@nodejs-github-bot

This comment was marked as outdated.

@codecov

codecov Bot commented Aug 25, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 90.13%. Comparing base (4b5e86c) to head (225349a).
⚠️ Report is 24 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main   #64024      +/-   ##
==========================================
- Coverage   90.14%   90.13%   -0.01%     
==========================================
  Files         751      751              
  Lines      253679   253700      +21     
  Branches    47789    47800      +11     
==========================================
+ Hits       228671   228684      +13     
- Misses      16264    16272       +8     
  Partials     8744     8744              
Files with missing lines Coverage Δ
lib/internal/event_target.js 98.80% <100.00%> (+0.02%) ⬆️

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

@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 that have at least one approval, no outstanding review comments, and a CI started. events Issues and PRs related to the events subsystem / EventEmitter. needs-ci PRs that need a full CI run.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

EventTarget.addEventListener(..., {signal}) abort signal listeners can get GC'd and never remove event listeners

5 participants