You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
// repro.mjs — run with a DSN pointing at any HTTP server that answers 200, e.g. a stub on localhostimport*asSentryfrom"@sentry/node"Sentry.init({dsn: process.env.SENTRY_DSN,release: "1.0.0",// any release, so the process session is sendableskipOpenTelemetrySetup: true,// we run our own OTel pipeline elsewheretracesSampleRate: undefined,// tracing off})console.log("done; letting the process exit naturally")
CPU sits at 60–100% against a local stub; against a real DSN the loop is network-bound but the process is still immortal. We hit this in a Cloud Run job running database migrations, which hung until its 600 s task timeout on every deploy after upgrading from 10.54.
What appears to happen:
fix(v10/node): Only end the process session when it is still ok #23731 (10.72) makes processSessionIntegration end the session on beforeExit when its status is ok, so a healthy process now sends a session envelope at exit (previously the condition was inverted and healthy processes sent nothing).
That transport request is instrumented by the http integration. With no OTel setup and tracing off, its span is dropped and recordDroppedEvent("no_parent_span", "span") records an outcome.
The client-report beforeExit listener flushes the new outcome → another instrumented request → another no_parent_span outcome → beforeExit again → …
await Sentry.close() before exiting also avoids it, but the default behaviour of a process that simply finishes should not be to hang.
Additional Context
Suggested fixes: don't record a no_parent_span outcome for the SDK's own transport requests, and/or don't re-arm the client-report flush from within a beforeExit flush (e.g. only flush outcomes that existed before the current beforeExit tick).
Is there an existing issue for this?
How do you use Sentry?
Sentry Saas (sentry.io)
Which SDK are you using?
@sentry/node
SDK Version
10.73.0 (also 10.72.0; 10.54.0 is fine)
Framework Version
Node 22.22.2
Link to Sentry event
No response
Reproduction Example/SDK Setup
Stub receiver used for the counts below:
Steps to Reproduce
node stub.mjsSENTRY_DSN=http://k@localhost:9999/1 node repro.mjsExpected Result
The process sends the session (and at most one client report) and exits.
Actual Result
The process never exits. The stub receives one
sessionenvelope and then an endless stream ofclient_reportenvelopes, each containing:{"discarded_events":[{"reason":"no_parent_span","category":"span","quantity":1}]}CPU sits at 60–100% against a local stub; against a real DSN the loop is network-bound but the process is still immortal. We hit this in a Cloud Run job running database migrations, which hung until its 600 s task timeout on every deploy after upgrading from 10.54.
What appears to happen:
processSessionIntegrationend the session onbeforeExitwhen its status isok, so a healthy process now sends asessionenvelope at exit (previously the condition was inverted and healthy processes sent nothing).recordDroppedEvent("no_parent_span", "span")records an outcome.beforeExitlistener flushes the new outcome → another instrumented request → anotherno_parent_spanoutcome →beforeExitagain → …Confirmed by elimination:
{ dsn, release }{ dsn, release, skipOpenTelemetrySetup: true }{ dsn, release, skipOpenTelemetrySetup: true, sendClientReports: false }await Sentry.close()before exiting also avoids it, but the default behaviour of a process that simply finishes should not be to hang.Additional Context
Suggested fixes: don't record a
no_parent_spanoutcome for the SDK's own transport requests, and/or don't re-arm the client-report flush from within abeforeExitflush (e.g. only flush outcomes that existed before the currentbeforeExittick).Priority
Medium