Skip to content

Conversation

Han5991
Copy link
Contributor

@Han5991 Han5991 commented Oct 7, 2025

Description

This PR fixes a bug where the removeListener event was not being emitted when the last listener was removed from an EventEmitter.

Background

When removeListener() is called and the last listener is removed (_eventsCount === 0), the code path that emits the removeListener event
was being skipped. This was because the emission logic was inside the else block of the event count check.

This issue particularly affects once() listeners, which automatically call removeListener() after execution. If the once listener was the
last listener, the removeListener event would not fire.

Changes

  • lib/events.js: Moved the removeListener event emission outside the conditional block to ensure it always executes when a listener is
    removed
  • test/parallel/test-event-emitter-remove-listeners.js: Added test coverage for once() listeners with removeListener event monitoring

Test Plan

./node test/parallel/test-event-emitter-remove-listeners.js
make test-ci

All tests pass, including the new test case that verifies removeListener events are emitted when once() listeners are automatically removed.

Checklist

- tests are included
- documentation is not affected
- make -j4 test passes locally
image

Related Issues

fixes: #59977

@nodejs-github-bot nodejs-github-bot added events Issues and PRs related to the events subsystem / EventEmitter. needs-ci PRs that need a full CI run. labels Oct 7, 2025
@Han5991 Han5991 marked this pull request as ready for review October 7, 2025 05:54
Copy link

codecov bot commented Oct 7, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 88.53%. Comparing base (bfc81ca) to head (d322e4d).

Additional details and impacted files
@@            Coverage Diff             @@
##             main   #60137      +/-   ##
==========================================
- Coverage   88.55%   88.53%   -0.02%     
==========================================
  Files         704      704              
  Lines      208087   208088       +1     
  Branches    40019    40014       -5     
==========================================
- Hits       184266   184233      -33     
- Misses      15818    15862      +44     
+ Partials     8003     7993      -10     
Files with missing lines Coverage Δ
lib/events.js 99.83% <100.00%> (+<0.01%) ⬆️

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

Adds test coverage for the removeListener event being emitted
when a once() listener is automatically removed after execution.
This verifies that streams and other EventEmitters correctly
emit removeListener events when once() wrappers clean up.
When the last listener is removed and _eventsCount becomes 0,
the removeListener event was not being emitted because the check
was inside the else block. This moves the removeListener emission
outside the conditional to ensure it always fires when a listener
is removed.
@Han5991 Han5991 force-pushed the fix-events-remove-listener-emission branch from 074f626 to d322e4d Compare October 9, 2025 23:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
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.

sockets no longer emit removeListener events in v20.11.0
2 participants