ChangeStream leaks `error` listeners when used with `events.once(..., { signal: AbortSignal.timeout(...) })`

XMLWordPrintableJSON

    • Type: Bug
    • Resolution: Unresolved
    • Priority: Unknown
    • None
    • Affects Version/s: 6.8.0
    • Component/s: Change Streams
    • None
    • None
    • None
    • None
    • None
    • None
    • None

      Summary

      ChangeStream leaks `error` listeners when used with `events.once(...,

      { signal: AbortSignal.timeout(...) }

      )`.

      Environment

      • Node.js: 24.x (also reproduced on 25.x)
      • mongodb driver: current latest in project setup
      • MongoDB: 8.x replica set

      Repro

      ```js
      import

      { once }

      from 'node:events';
      import

      { MongoClient }

      from 'mongodb';

      const client = new MongoClient('mongodb://localhost:27017/agent?replicaSet=travel');
      await client.connect();

      const chats = client.db('agent').collection('chats');
      const stream = chats.watch();

      setInterval(() => {
      once(stream, 'change',

      { signal: AbortSignal.timeout(50) }

      ).catch(() => {});
      }, 100);
      ```

      Actual Result

      ```txt
      MaxListenersExceededWarning: Possible EventEmitter memory leak detected.
      11 error listeners added to [ReadableCursorStream].
      ```

      Control Case (works as expected)

      ```js
      import

      { once, EventEmitter }

      from 'node:events';

      const ee = new EventEmitter();

      setInterval(() => {
      once(ee, 'change',

      { signal: AbortSignal.timeout(50) }

      ).catch(() => {});
      }, 100);
      ```

      No warning in the same scenario.

      Why this looks driver-specific

      With `--trace-warnings`, stack points to `ChangeStream._streamEvents` adding `stream.on('error', ...)` repeatedly.

      Expected

      Using `events.once` repeatedly with timeout-abort should not accumulate internal listeners in `ChangeStream`/`ReadableCursorStream` until warning threshold.

      Actual

      `error` listeners on internal cursor stream accumulate and trigger `MaxListenersExceededWarning`.

      Additional Notes

      If needed, I can provide a minimal runnable repo.

            Assignee:
            Unassigned
            Reporter:
            Evgeny Vlasenko
            None
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated: