Skip to content

feat(node)!: Drop custom startNewTrace implementation - #22715

Open
mydea wants to merge 2 commits into
developfrom
fn/start-new-trace
Open

feat(node)!: Drop custom startNewTrace implementation#22715
mydea wants to merge 2 commits into
developfrom
fn/start-new-trace

Conversation

@mydea

@mydea mydea commented Jul 27, 2026

Copy link
Copy Markdown
Member

All tests pass without this, it seems to work fine with the base implementation.

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 2 potential issues.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit aff9af4. Configure here.

if (acs.startNewTrace) {
return acs.startNewTrace(callback);
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OTEL spans ignore startNewTrace

High Severity

Removing the OpenTelemetry startNewTrace override drops remote span injection into OTEL context. In Node, Sentry.startInactiveSpan / startSpan root creation still goes through SentryTracer, which calls startNewTrace again per root instead of reusing the callback’s propagation context, so spans inside one startNewTrace can get different traceIds and won’t match the scope set by the API.

Additional Locations (2)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit aff9af4. Configure here.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verified that this bb finding is valid. (Will provide more details, writing up, don't merge for now please.)

});
});

describe('startNewTrace', () => {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed OTEL startNewTrace tests

Medium Severity

This feat change deletes the entire OpenTelemetry startNewTrace test suite without adding integration, E2E, or equivalent unit coverage elsewhere. Per PR review guidelines, feature work should include tests that assert the new behavior, especially for Node/OTEL trace propagation.

Fix in Cursor Fix in Web

Triggered by project rule: PR Review Guidelines for Cursor Bot

Reviewed by Cursor Bugbot for commit aff9af4. Configure here.

@github-actions

Copy link
Copy Markdown
Contributor

size-limit report 📦

Path Size % Change Change
@sentry/browser 28.02 kB - -
@sentry/browser - with treeshaking flags 26.46 kB - -
@sentry/browser (incl. Tracing) 46.54 kB - -
@sentry/browser (incl. Tracing + Span Streaming) 47.46 kB - -
@sentry/browser (incl. Tracing, Profiling) 51.3 kB - -
@sentry/browser (incl. Tracing, Replay) 85.87 kB - -
@sentry/browser (incl. Tracing, Replay) - with treeshaking flags 75.51 kB - -
@sentry/browser (incl. Tracing, Replay with Canvas) 90.58 kB - -
@sentry/browser (incl. Tracing, Replay, Feedback) 103.22 kB - -
@sentry/browser (incl. Feedback) 45.2 kB - -
@sentry/browser (incl. sendFeedback) 32.82 kB - -
@sentry/browser (incl. FeedbackAsync) 37.86 kB - -
@sentry/browser (incl. Metrics) 29.12 kB - -
@sentry/browser (incl. Logs) 29.34 kB - -
@sentry/browser (incl. Metrics & Logs) 30.05 kB - -
@sentry/react 29.8 kB - -
@sentry/react (incl. Tracing) 48.85 kB - -
@sentry/vue 33.97 kB - -
@sentry/vue (incl. Tracing) 48.53 kB - -
@sentry/svelte 28.04 kB - -
CDN Bundle 30.31 kB -0.04% -12 B 🔽
CDN Bundle (incl. Tracing) 47.7 kB -0.03% -11 B 🔽
CDN Bundle (incl. Logs, Metrics) 31.89 kB -0.04% -10 B 🔽
CDN Bundle (incl. Tracing, Logs, Metrics) 49.07 kB -0.02% -9 B 🔽
CDN Bundle (incl. Replay, Logs, Metrics) 71.16 kB -0.02% -12 B 🔽
CDN Bundle (incl. Tracing, Replay) 85.3 kB -0.02% -9 B 🔽
CDN Bundle (incl. Tracing, Replay, Logs, Metrics) 86.6 kB -0.02% -9 B 🔽
CDN Bundle (incl. Tracing, Replay, Feedback) 91.11 kB -0.02% -10 B 🔽
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics) 92.38 kB -0.01% -8 B 🔽
CDN Bundle - uncompressed 90.21 kB -0.06% -48 B 🔽
CDN Bundle (incl. Tracing) - uncompressed 143.17 kB -0.04% -48 B 🔽
CDN Bundle (incl. Logs, Metrics) - uncompressed 94.92 kB -0.06% -48 B 🔽
CDN Bundle (incl. Tracing, Logs, Metrics) - uncompressed 147.15 kB -0.04% -48 B 🔽
CDN Bundle (incl. Replay, Logs, Metrics) - uncompressed 219.69 kB -0.03% -48 B 🔽
CDN Bundle (incl. Tracing, Replay) - uncompressed 262.43 kB -0.02% -48 B 🔽
CDN Bundle (incl. Tracing, Replay, Logs, Metrics) - uncompressed 266.39 kB -0.02% -48 B 🔽
CDN Bundle (incl. Tracing, Replay, Feedback) - uncompressed 276.13 kB -0.02% -48 B 🔽
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics) - uncompressed 280.08 kB -0.02% -48 B 🔽
@sentry/nextjs (client) 51.41 kB - -
@sentry/sveltekit (client) 47.01 kB - -
@sentry/core/server 79.56 kB -0.02% -12 B 🔽
@sentry/core/browser 51.52 kB -0.03% -15 B 🔽
@sentry/node 112.39 kB -0.08% -82 B 🔽
@sentry/node (incl. diagnostics channel injection) 156.54 kB -0.07% -101 B 🔽
@sentry/node/import (ESM hook with diagnostics-channel injection) 166 B - -
@sentry/node - without tracing 61.94 kB -0.12% -70 B 🔽
@sentry/aws-serverless 72.22 kB -0.11% -74 B 🔽
@sentry/cloudflare (withSentry) - minified 195.9 kB -0.03% -46 B 🔽
@sentry/cloudflare (withSentry) 482.41 kB -0.02% -95 B 🔽

View base workflow run

@mydea
mydea marked this pull request as ready for review July 28, 2026 07:48
@mydea
mydea requested a review from a team as a code owner July 28, 2026 07:49
@mydea
mydea requested review from JPeer264 and isaacs and removed request for a team July 28, 2026 07:49
@isaacs

isaacs commented Jul 28, 2026

Copy link
Copy Markdown
Member

I think this PR is not feasible, though it does showcase a shortcoming in our tests that would've made that more clear.

In packages/opentelemetry/src/tracer.ts, there's this, when there's no parent span and no remote parent:

    return startNewTrace(() =>
      _INTERNAL_startInactiveSpan({
        ...sentryOptions,
        parentSpan: hasExplicitContext ? null : undefined,
      }),
    );

Every parentless root span created through OTEL calls core startNewTrace again, and core startNewTrace in packages/core/src/tracing/trace.ts generates a fresh traceId each time and calls withActiveSpan(null, ...), which deletes the active span from the OTEL context. So inside one user Sentry.startNewTrace(cb), every startInactiveSpan/startSpan root in cb goes through this method at the end of _startSentrySpan, mints its own trace, and none of them matches the traceId the API set on the scope's context.

The OTEL override avoided this by injecting an isRemote SpanContext into the OTEL context in trace.setSpanContext(context.active(), { ..., isRemote: true })), so inner spans took the remote-parent branch (_startRootSpanWithRemoteParent in packages/opentelemetry/src/tracer.ts on 131-133) and reused the injected traceId.

The propagator in packages/opentelemetry/src/propagator.ts relies on that isRemote flag, where a remote active span is what makes outgoing HTTP requests inside the callback carry the new trace id.

  // If we have a remote span, the spanId should be considered as the parentSpanId, not spanId itself
  // Instead, we use a virtual (generated) spanId for propagation
  if (span?.spanContext().isRemote) {

So, on Node, spans created inside Sentry.startNewTrace(() => end up on different traces from each other and from the propagation context the API just set, and outgoing requests in the callback no longer propagate the new trace.

In digging into this, I created a test that can be applied on develop that would've helped catch this, and a regression test on the PR branch that shows the failure: https://gist.github.com/isaacs/6d725c4ca3f949b751a3ceb0375c23df

I tried to see if there was a way to detect that we're in a remote span and not re-enter the startNewTrace call for root spans that are already in a trace, but I couldn't find any way to do that without creating some kind of override even worse than the one being removed, unfortunately 😕

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants