From 15928eb6440b0d146157a745202dc0f3384f6fcd Mon Sep 17 00:00:00 2001 From: Rintaro Itokawa Date: Sat, 5 Sep 2026 04:07:24 +0900 Subject: [PATCH] fix(teeny-request): avoid MaxListenersExceededWarning in stream mode node-fetch v3 attaches several internal pipeline listeners to the response body stream. Combined with teeny-request's own error forwarding and pipeline wiring plus downstream consumers such as @google-cloud/storage, the default limit of 10 listeners is legitimately exceeded, emitting two MaxListenersExceededWarning messages on every streamed download. This change removes the listener limit on the fetch response body stream, which is internal to teeny-request and short-lived. Fixes #9185 --- core/packages/teeny-request/src/index.ts | 6 ++++++ core/packages/teeny-request/test/index.ts | 12 ++++++++++++ 2 files changed, 18 insertions(+) diff --git a/core/packages/teeny-request/src/index.ts b/core/packages/teeny-request/src/index.ts index 931861ad798c..1310d015e8bb 100644 --- a/core/packages/teeny-request/src/index.ts +++ b/core/packages/teeny-request/src/index.ts @@ -293,6 +293,12 @@ function teenyRequest( teenyRequest.stats.requestFinished(); responseStream = res.body; + // node-fetch v3's internal pipeline listeners plus the wiring below + // legitimately exceed the default limit of 10, warning on every + // streamed response + // see: https://github.com/googleapis/google-cloud-node/issues/9185 + responseStream.setMaxListeners(0); + responseStream.on('error', (err: Error) => { requestStream.emit('error', err); }); diff --git a/core/packages/teeny-request/test/index.ts b/core/packages/teeny-request/test/index.ts index e34d697a2a58..0f80d277bba6 100644 --- a/core/packages/teeny-request/test/index.ts +++ b/core/packages/teeny-request/test/index.ts @@ -298,6 +298,18 @@ describe('teeny', () => { }); }); + // see: https://github.com/googleapis/google-cloud-node/issues/9185 + it('should remove the listener limit on the fetch response stream', done => { + const scope = mockJson(); + const stream = teenyRequest({uri}).on('error', done); + stream.on('response', res => { + assert.strictEqual(res.body.getMaxListeners(), 0); + scope.done(); + done(); + }); + stream.resume(); + }); + it('should expose TeenyStatistics instance', () => { assert.ok(teenyRequest.stats instanceof TeenyStatistics); });