diff --git a/CHANGELOG.md b/CHANGELOG.md index 61f149124..21fd05b6a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Fixed +- Silenced a false-positive `MaxListenersExceededWarning` logged on every request proxied through an external rewrite. [#1697](https://github.com/sourcebot-dev/sourcebot/pull/1697) + ## [5.1.15] - 2026-09-29 ### Added diff --git a/packages/web/src/instrumentation.ts b/packages/web/src/instrumentation.ts index 2af3ddcef..52720b490 100644 --- a/packages/web/src/instrumentation.ts +++ b/packages/web/src/instrumentation.ts @@ -1,4 +1,5 @@ import * as Sentry from '@sentry/nextjs'; +import type { ServerResponse } from 'node:http'; export async function register() { if (process.env.NEXT_RUNTIME === 'nodejs') { @@ -10,6 +11,21 @@ export async function register() { } if (process.env.NEXT_RUNTIME === 'nodejs') { + // Proxied rewrites (`/ingest/*` for PostHog, the `/monitoring` Sentry + // tunnel) legitimately attach 11 `close` listeners to each response: 9 + // from Next's rewrite proxy plus 2 from Sentry. That crosses Node's + // default limit of 10 and logs a MaxListenersExceededWarning on every + // such request, even though the listeners are released with the + // response. The request start channel fires before Next handles the + // request, and scoping the raise to responses keeps the warning + // meaningful for every other emitter. This can be removed once Next + // trims its proxy listeners. + // @see: https://github.com/vercel/next.js/issues/97757 + const { subscribe } = await import('node:diagnostics_channel'); + subscribe('http.server.request.start', (message) => { + (message as { response?: ServerResponse }).response?.setMaxListeners(20); + }); + const { startMetricsServer } = await import('./metricsServer'); startMetricsServer();