From cd9989132c9fcaed556df90da273103536f81456 Mon Sep 17 00:00:00 2001 From: Lukas Stracke Date: Tue, 21 Jul 2026 14:37:01 +0200 Subject: [PATCH 1/4] fix(core): Avoid propagating `baggage: "undefined"` when DSC is missing --- packages/core/src/fetch.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/core/src/fetch.ts b/packages/core/src/fetch.ts index bfe78d499260..1c0083f33f17 100644 --- a/packages/core/src/fetch.ts +++ b/packages/core/src/fetch.ts @@ -222,7 +222,11 @@ export function _INTERNAL_getTracingHeadersForFetchRequest( const originalHeaders = fetchOptionsObj.headers || (isRequest(request) ? request.headers : undefined); if (!originalHeaders) { - return { ...traceHeaders }; + return { + 'sentry-trace': sentryTrace, + ...(baggage && { baggage }), + ...(traceparent && { traceparent }), + }; } else if (isHeaders(originalHeaders)) { const newHeaders = new Headers(originalHeaders); From 48f895c383bd795ebfe895ff25f15b8da8761466 Mon Sep 17 00:00:00 2001 From: Lukas Stracke Date: Tue, 21 Jul 2026 14:37:44 +0200 Subject: [PATCH 2/4] add integration test --- .../standalone-without-baggage/init.js | 10 ++++ .../standalone-without-baggage/subject.js | 3 ++ .../standalone-without-baggage/template.html | 11 +++++ .../standalone-without-baggage/test.ts | 48 +++++++++++++++++++ 4 files changed, 72 insertions(+) create mode 100644 dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/standalone-without-baggage/init.js create mode 100644 dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/standalone-without-baggage/subject.js create mode 100644 dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/standalone-without-baggage/template.html create mode 100644 dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/standalone-without-baggage/test.ts diff --git a/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/standalone-without-baggage/init.js b/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/standalone-without-baggage/init.js new file mode 100644 index 000000000000..e2dd69ede824 --- /dev/null +++ b/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/standalone-without-baggage/init.js @@ -0,0 +1,10 @@ +import * as Sentry from '@sentry/browser'; + +window.Sentry = Sentry; + +Sentry.init({ + dsn: 'https://public@dsn.ingest.sentry.io/1337', + integrations: [Sentry.browserTracingIntegration()], + tracePropagationTargets: ['sentry-test-external.io'], + tracesSampleRate: 1, +}); diff --git a/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/standalone-without-baggage/subject.js b/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/standalone-without-baggage/subject.js new file mode 100644 index 000000000000..179c0203e14c --- /dev/null +++ b/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/standalone-without-baggage/subject.js @@ -0,0 +1,3 @@ +Sentry.startSpan({ name: 'standalone_span', experimental: { standalone: true } }, () => { + fetch('http://sentry-test-external.io'); +}); diff --git a/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/standalone-without-baggage/template.html b/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/standalone-without-baggage/template.html new file mode 100644 index 000000000000..2238e1ac8cc3 --- /dev/null +++ b/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/standalone-without-baggage/template.html @@ -0,0 +1,11 @@ + + + + + + + + diff --git a/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/standalone-without-baggage/test.ts b/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/standalone-without-baggage/test.ts new file mode 100644 index 000000000000..2700c8aa5077 --- /dev/null +++ b/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/standalone-without-baggage/test.ts @@ -0,0 +1,48 @@ +import { expect } from '@playwright/test'; +import type { SpanEnvelope } from '@sentry/core'; +import { sentryTest } from '../../../../utils/fixtures'; +import { + getMultipleSentryEnvelopeRequests, + properFullEnvelopeRequestParser, + shouldSkipTracingTest, +} from '../../../../utils/helpers'; + +const TRACE_ID = '12345678901234567890123456789012'; +const OUTGOING_REQUEST_URL = 'http://sentry-test-external.io'; + +sentryTest( + 'omits the trace envelope header when a standalone span continues a trace without baggage', + async ({ getLocalTestUrl, page }) => { + sentryTest.skip(shouldSkipTracingTest()); + + const url = await getLocalTestUrl({ testDir: __dirname }); + await page.route(OUTGOING_REQUEST_URL, route => route.fulfill({ status: 200, body: 'ok' })); + const outgoingRequestPromise = page.waitForRequest(OUTGOING_REQUEST_URL); + + const [spanEnvelope] = await getMultipleSentryEnvelopeRequests( + page, + 1, + { url, envelopeType: 'span' }, + properFullEnvelopeRequestParser, + ); + const outgoingRequest = await outgoingRequestPromise; + + expect(spanEnvelope[0]).toEqual({ + sent_at: expect.any(String), + }); + + // To be clear: This is _expected_ behavior, not a bug. + // SDKs must assume that an incoming `sentry-trace` but no `baggage` meta tag means that the + // trace was started from an SDK that's not yet compatible with the DSC or baggage propagation. + // The test demonstrates that the SDK as expected continues the trace but does not send a `trace` + // header, nor a baggage header. + expect(spanEnvelope[0].trace).toBeUndefined(); + + expect(spanEnvelope[1]).toHaveLength(1); + expect(spanEnvelope[1][0][1].trace_id).toBe(TRACE_ID); + + const outgoingRequestHeaders = outgoingRequest.headers(); + expect(outgoingRequestHeaders['sentry-trace']).toMatch(new RegExp(`^${TRACE_ID}-[\\da-f]{16}-1$`)); + expect(outgoingRequestHeaders['baggage']).toBeUndefined(); + }, +); From 9c81cdcb1cb509a946ea071510c06bd27f4bc7bf Mon Sep 17 00:00:00 2001 From: Lukas Stracke Date: Tue, 21 Jul 2026 15:54:37 +0200 Subject: [PATCH 3/4] also include plain object headers --- packages/core/src/fetch.ts | 4 ++-- packages/core/test/lib/fetch.test.ts | 15 +++++++++++++++ 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/packages/core/src/fetch.ts b/packages/core/src/fetch.ts index 1c0083f33f17..bb69a1b0025e 100644 --- a/packages/core/src/fetch.ts +++ b/packages/core/src/fetch.ts @@ -296,11 +296,11 @@ export function _INTERNAL_getTracingHeadersForFetchRequest( const newHeaders: { 'sentry-trace': string; - baggage: string | undefined; + baggage?: string; traceparent?: string; } = Object.assign({}, originalHeaders, { 'sentry-trace': (existingSentryTraceHeader as string | undefined) ?? sentryTrace, - baggage: newBaggageHeaders.length > 0 ? newBaggageHeaders.join(',') : undefined, + ...(newBaggageHeaders.length > 0 && { baggage: newBaggageHeaders.join(',') }), }); if (propagateTraceparent && traceparent && !existingTraceparentHeader) { diff --git a/packages/core/test/lib/fetch.test.ts b/packages/core/test/lib/fetch.test.ts index 6cfdb74e8a19..b09886172969 100644 --- a/packages/core/test/lib/fetch.test.ts +++ b/packages/core/test/lib/fetch.test.ts @@ -69,6 +69,21 @@ describe('_INTERNAL_getTracingHeadersForFetchRequest', () => { }); }); + it('omits baggage from headers object when no baggage is available', () => { + vi.mocked(traceData.getTraceData).mockReturnValueOnce({ + 'sentry-trace': DEFAULT_SENTRY_TRACE, + }); + + const returnedHeaders = _INTERNAL_getTracingHeadersForFetchRequest('/api/test', { + headers: { 'custom-header': 'custom-value' }, + }); + + expect(returnedHeaders).toStrictEqual({ + 'sentry-trace': DEFAULT_SENTRY_TRACE, + 'custom-header': 'custom-value', + }); + }); + it('attaches sentry headers to a Headers instance', () => { const returnedHeaders = _INTERNAL_getTracingHeadersForFetchRequest('/api/test', { headers: new Headers({ 'custom-header': 'custom-value' }), From 861bc457846419c157cc7905284a30393cfa0cb2 Mon Sep 17 00:00:00 2001 From: Lukas Stracke Date: Tue, 21 Jul 2026 16:02:23 +0200 Subject: [PATCH 4/4] fmt --- .../standalone-without-baggage/template.html | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/standalone-without-baggage/template.html b/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/standalone-without-baggage/template.html index 2238e1ac8cc3..f98e1c83e643 100644 --- a/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/standalone-without-baggage/template.html +++ b/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/standalone-without-baggage/template.html @@ -2,10 +2,7 @@ - +