fix(nextjs): universal random tunnel path support - #18257

Merged
logaretm merged 16 commits into
developfrom
awad/js-549-adblock-plus-blocking-requests-to-sentry-and-monitoring
Nov 24, 2025
Merged

fix(nextjs): universal random tunnel path support#18257
logaretm merged 16 commits into
developfrom
awad/js-549-adblock-plus-blocking-requests-to-sentry-and-monitoring

Conversation

@logaretm

@logaretmlogaretm commented Nov 19, 2025

Copy link
Copy Markdown
Member

When using Next.js with Turbopack and the Sentry tunnel route feature (tunnelRoute: true), several issues prevented events from being sent properly:

1. Tunnel Route Consistency (Turbopack)

Problem: Random tunnel routes were generated separately for client and server builds in Turbopack.

Solution: Implemented processs-level caching in withSentryConfig.ts:

  • Extract tunnel route resolution into resolveTunnelRoute() function
  • Use process.env to store the random tunnel value across server/client builds.

2. Filter Tunnel Request Spans

Problem: Requests to the tunnel route (before rewrite) and to Sentry ingest URLs (after rewrite) were creating spans that polluted Sentry with internal instrumentation noise, spans were being created by the middleware and OTEL node.js fetch instrumentation.

Solution: Implemented server-side span filtering:

  • Created dropMiddlewareTunnelRequests() utility to detect and drop tunnel-related spans
  • Filter spans originating from Middleware.execute (Next.js middleware)
  • Filter spans originating from auto.http.otel.node_fetch (Node.js fetch instrumentation)
  • Check both local tunnel paths and Sentry ingest URLs (using isSentryRequestSpan from @sentry/opentelemetry)
  • Mark matching spans with TRANSACTION_ATTR_SHOULD_DROP_TRANSACTION to prevent them from being sent
  • I tried beforeSampling hook but it didn't work for some reason, so I stuck with the drop attribute.

The final issue was excluding the tunnel requests from the middleware/proxy, but there are many blockers for a solution:

  1. The config must be statically analyzable, so we cannot expose withSentryMiddlewareConfig wrapper of any kind.
  2. Warning the user doesn't help much because they can't do anything about it since the tunnel route is random.
  3. Tested out writing a loader for turbopack/webpack to inject the tunnel into the matcher as an array but user existing matcher can match still.
  4. Only way is to inject an exclusion match into the user existing matcher, if it is an array then we need to inject it into each single entry.

I may explore this further later with a loader for both webpack/turbopack, and figure out a reliable way to inject the negative matchers into the user expressions.

@linear

linearBot commented Nov 19, 2025

Copy link
Copy Markdown

@logaretmlogaretm changed the title fix(nextjs): Turbopack random tunnel supportfix(nextjs): Turbopack random tunnel path supportNov 19, 2025
@logaretm
logaretmforce-pushed the awad/js-549-adblock-plus-blocking-requests-to-sentry-and-monitoring branch from a230c8b to dd615c6CompareNovember 20, 2025 09:37
@github-actions

github-actionsBot commented Nov 20, 2025

Copy link
Copy Markdown
Contributor

size-limit report 📦

PathSize% ChangeChange
@sentry/browser24.7 kB--
@sentry/browser - with treeshaking flags23.2 kB--
@sentry/browser (incl. Tracing)41.43 kB--
@sentry/browser (incl. Tracing, Profiling)45.75 kB--
@sentry/browser (incl. Tracing, Replay)79.85 kB--
@sentry/browser (incl. Tracing, Replay) - with treeshaking flags69.57 kB--
@sentry/browser (incl. Tracing, Replay with Canvas)84.55 kB--
@sentry/browser (incl. Tracing, Replay, Feedback)96.77 kB--
@sentry/browser (incl. Feedback)41.38 kB--
@sentry/browser (incl. sendFeedback)29.39 kB--
@sentry/browser (incl. FeedbackAsync)34.33 kB--
@sentry/react26.41 kB--
@sentry/react (incl. Tracing)43.43 kB--
@sentry/vue29.15 kB--
@sentry/vue (incl. Tracing)43.23 kB--
@sentry/svelte24.72 kB--
CDN Bundle27.02 kB--
CDN Bundle (incl. Tracing)42.02 kB--
CDN Bundle (incl. Tracing, Replay)78.53 kB--
CDN Bundle (incl. Tracing, Replay, Feedback)84.02 kB--
CDN Bundle - uncompressed79.17 kB--
CDN Bundle (incl. Tracing) - uncompressed124.55 kB--
CDN Bundle (incl. Tracing, Replay) - uncompressed240.59 kB--
CDN Bundle (incl. Tracing, Replay, Feedback) - uncompressed253.35 kB--
@sentry/nextjs (client)45.84 kB--
@sentry/sveltekit (client)41.79 kB--
@sentry/node-core51.02 kB--
@sentry/node159.34 kB--
@sentry/node - without tracing92.88 kB-0.03%-19 B 🔽
@sentry/aws-serverless106.64 kB--

View base workflow run

@logaretm
logaretmforce-pushed the awad/js-549-adblock-plus-blocking-requests-to-sentry-and-monitoring branch from 795af30 to f787df1CompareNovember 20, 2025 15:56
@logaretmlogaretm changed the title fix(nextjs): Turbopack random tunnel path supportfix(nextjs): universal random tunnel path supportNov 21, 2025
@github-actions

github-actionsBot commented Nov 21, 2025

Copy link
Copy Markdown
Contributor

node-overhead report 🧳

Note: This is a synthetic benchmark with a minimal express app and does not necessarily reflect the real-world performance impact in an application.

ScenarioRequests/s% of BaselinePrev. Requests/sChange %
GET Baseline8,807-8,853-1%
GET With Sentry1,63219%1,777-8%
GET With Sentry (error only)6,05669%6,031+0%
POST Baseline1,191-1,207-1%
POST With Sentry59450%597-1%
POST With Sentry (error only)1,03287%1,060-3%
MYSQL Baseline3,190-3,301-3%
MYSQL With Sentry42113%490-14%
MYSQL With Sentry (error only)2,61582%2,724-4%

View base workflow run

@logaretm
logaretmforce-pushed the awad/js-549-adblock-plus-blocking-requests-to-sentry-and-monitoring branch from 4fab2f0 to 856a4d1CompareNovember 21, 2025 11:26
@logaretm
logaretm marked this pull request as ready for review November 21, 2025 11:26
@logaretm
logaretmforce-pushed the awad/js-549-adblock-plus-blocking-requests-to-sentry-and-monitoring branch from d5442a6 to b332e39CompareNovember 21, 2025 13:11
@logaretm
logaretmforce-pushed the awad/js-549-adblock-plus-blocking-requests-to-sentry-and-monitoring branch from b332e39 to 981121cCompareNovember 21, 2025 13:12
}) satisfies EventProcessor,
{ id: 'NextLowQualityTransactionsFilter' },
),
);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Bug: Edge runtime missing tunnel route transaction filter

The event processor on the edge runtime only filters transactions based on the TRANSACTION_ATTR_SHOULD_DROP_TRANSACTION attribute, but lacks the explicit tunnel route transaction name check present in the server-side event processor. This asymmetry creates a defensive gap: if span marking fails for any reason, server-side transactions are still filtered by name, but edge-side transactions would slip through. For consistency and robustness, the edge-side event processor should include the same explicit tunnel route check that filters POST requests to the tunnel path.

Fix in CursorFix in Web

// env works well here
// https://linear.app/getsentry/issue/JS-549/adblock-plus-blocking-requests-to-sentry-and-monitoring-tunnel
if (resolvedTunnelRoute) {
process.env.__SENTRY_TUNNEL_ROUTE__ = resolvedTunnelRoute;

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.

Nice find!

@logaretm
logaretm merged commit 4b92c64 into developNov 24, 2025
66 checks passed
@logaretm
logaretm deleted the awad/js-549-adblock-plus-blocking-requests-to-sentry-and-monitoring branch November 24, 2025 15:41
Sign up for freeto 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.

3 participants

@logaretm@chargome@github-advanced-security
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

fix(nextjs): universal random tunnel path support - #18257

Merged
logaretm merged 16 commits into
developfrom
awad/js-549-adblock-plus-blocking-requests-to-sentry-and-monitoring
Nov 24, 2025
Merged

fix(nextjs): universal random tunnel path support#18257
logaretm merged 16 commits into
developfrom
awad/js-549-adblock-plus-blocking-requests-to-sentry-and-monitoring

Conversation

@logaretm

@logaretmlogaretm commented Nov 19, 2025

Copy link
Copy Markdown
Member

When using Next.js with Turbopack and the Sentry tunnel route feature (tunnelRoute: true), several issues prevented events from being sent properly:

1. Tunnel Route Consistency (Turbopack)

Problem: Random tunnel routes were generated separately for client and server builds in Turbopack.

Solution: Implemented processs-level caching in withSentryConfig.ts:

  • Extract tunnel route resolution into resolveTunnelRoute() function
  • Use process.env to store the random tunnel value across server/client builds.

2. Filter Tunnel Request Spans

Problem: Requests to the tunnel route (before rewrite) and to Sentry ingest URLs (after rewrite) were creating spans that polluted Sentry with internal instrumentation noise, spans were being created by the middleware and OTEL node.js fetch instrumentation.

Solution: Implemented server-side span filtering:

  • Created dropMiddlewareTunnelRequests() utility to detect and drop tunnel-related spans
  • Filter spans originating from Middleware.execute (Next.js middleware)
  • Filter spans originating from auto.http.otel.node_fetch (Node.js fetch instrumentation)
  • Check both local tunnel paths and Sentry ingest URLs (using isSentryRequestSpan from @sentry/opentelemetry)
  • Mark matching spans with TRANSACTION_ATTR_SHOULD_DROP_TRANSACTION to prevent them from being sent
  • I tried beforeSampling hook but it didn't work for some reason, so I stuck with the drop attribute.

The final issue was excluding the tunnel requests from the middleware/proxy, but there are many blockers for a solution:

  1. The config must be statically analyzable, so we cannot expose withSentryMiddlewareConfig wrapper of any kind.
  2. Warning the user doesn't help much because they can't do anything about it since the tunnel route is random.
  3. Tested out writing a loader for turbopack/webpack to inject the tunnel into the matcher as an array but user existing matcher can match still.
  4. Only way is to inject an exclusion match into the user existing matcher, if it is an array then we need to inject it into each single entry.

I may explore this further later with a loader for both webpack/turbopack, and figure out a reliable way to inject the negative matchers into the user expressions.

@linear

linearBot commented Nov 19, 2025

Copy link
Copy Markdown

@logaretmlogaretm changed the title fix(nextjs): Turbopack random tunnel supportfix(nextjs): Turbopack random tunnel path supportNov 19, 2025
@logaretm
logaretmforce-pushed the awad/js-549-adblock-plus-blocking-requests-to-sentry-and-monitoring branch from a230c8b to dd615c6CompareNovember 20, 2025 09:37
@github-actions

github-actionsBot commented Nov 20, 2025

Copy link
Copy Markdown
Contributor

size-limit report 📦

PathSize% ChangeChange
@sentry/browser24.7 kB--
@sentry/browser - with treeshaking flags23.2 kB--
@sentry/browser (incl. Tracing)41.43 kB--
@sentry/browser (incl. Tracing, Profiling)45.75 kB--
@sentry/browser (incl. Tracing, Replay)79.85 kB--
@sentry/browser (incl. Tracing, Replay) - with treeshaking flags69.57 kB--
@sentry/browser (incl. Tracing, Replay with Canvas)84.55 kB--
@sentry/browser (incl. Tracing, Replay, Feedback)96.77 kB--
@sentry/browser (incl. Feedback)41.38 kB--
@sentry/browser (incl. sendFeedback)29.39 kB--
@sentry/browser (incl. FeedbackAsync)34.33 kB--
@sentry/react26.41 kB--
@sentry/react (incl. Tracing)43.43 kB--
@sentry/vue29.15 kB--
@sentry/vue (incl. Tracing)43.23 kB--
@sentry/svelte24.72 kB--
CDN Bundle27.02 kB--
CDN Bundle (incl. Tracing)42.02 kB--
CDN Bundle (incl. Tracing, Replay)78.53 kB--
CDN Bundle (incl. Tracing, Replay, Feedback)84.02 kB--
CDN Bundle - uncompressed79.17 kB--
CDN Bundle (incl. Tracing) - uncompressed124.55 kB--
CDN Bundle (incl. Tracing, Replay) - uncompressed240.59 kB--
CDN Bundle (incl. Tracing, Replay, Feedback) - uncompressed253.35 kB--
@sentry/nextjs (client)45.84 kB--
@sentry/sveltekit (client)41.79 kB--
@sentry/node-core51.02 kB--
@sentry/node159.34 kB--
@sentry/node - without tracing92.88 kB-0.03%-19 B 🔽
@sentry/aws-serverless106.64 kB--

View base workflow run

@logaretm
logaretmforce-pushed the awad/js-549-adblock-plus-blocking-requests-to-sentry-and-monitoring branch from 795af30 to f787df1CompareNovember 20, 2025 15:56
@logaretmlogaretm changed the title fix(nextjs): Turbopack random tunnel path supportfix(nextjs): universal random tunnel path supportNov 21, 2025
@github-actions

github-actionsBot commented Nov 21, 2025

Copy link
Copy Markdown
Contributor

node-overhead report 🧳

Note: This is a synthetic benchmark with a minimal express app and does not necessarily reflect the real-world performance impact in an application.

ScenarioRequests/s% of BaselinePrev. Requests/sChange %
GET Baseline8,807-8,853-1%
GET With Sentry1,63219%1,777-8%
GET With Sentry (error only)6,05669%6,031+0%
POST Baseline1,191-1,207-1%
POST With Sentry59450%597-1%
POST With Sentry (error only)1,03287%1,060-3%
MYSQL Baseline3,190-3,301-3%
MYSQL With Sentry42113%490-14%
MYSQL With Sentry (error only)2,61582%2,724-4%

View base workflow run

@logaretm
logaretmforce-pushed the awad/js-549-adblock-plus-blocking-requests-to-sentry-and-monitoring branch from 4fab2f0 to 856a4d1CompareNovember 21, 2025 11:26
@logaretm
logaretm marked this pull request as ready for review November 21, 2025 11:26
@logaretm
logaretmforce-pushed the awad/js-549-adblock-plus-blocking-requests-to-sentry-and-monitoring branch from d5442a6 to b332e39CompareNovember 21, 2025 13:11
@logaretm
logaretmforce-pushed the awad/js-549-adblock-plus-blocking-requests-to-sentry-and-monitoring branch from b332e39 to 981121cCompareNovember 21, 2025 13:12
}) satisfies EventProcessor,
{ id: 'NextLowQualityTransactionsFilter' },
),
);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Bug: Edge runtime missing tunnel route transaction filter

The event processor on the edge runtime only filters transactions based on the TRANSACTION_ATTR_SHOULD_DROP_TRANSACTION attribute, but lacks the explicit tunnel route transaction name check present in the server-side event processor. This asymmetry creates a defensive gap: if span marking fails for any reason, server-side transactions are still filtered by name, but edge-side transactions would slip through. For consistency and robustness, the edge-side event processor should include the same explicit tunnel route check that filters POST requests to the tunnel path.

Fix in CursorFix in Web

// env works well here
// https://linear.app/getsentry/issue/JS-549/adblock-plus-blocking-requests-to-sentry-and-monitoring-tunnel
if (resolvedTunnelRoute) {
process.env.__SENTRY_TUNNEL_ROUTE__ = resolvedTunnelRoute;

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.

Nice find!

@logaretm
logaretm merged commit 4b92c64 into developNov 24, 2025
66 checks passed
@logaretm
logaretm deleted the awad/js-549-adblock-plus-blocking-requests-to-sentry-and-monitoring branch November 24, 2025 15:41
Sign up for freeto 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.

3 participants

@logaretm@chargome@github-advanced-security
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

fix(nextjs): universal random tunnel path support - #18257

Merged
logaretm merged 16 commits into
developfrom
awad/js-549-adblock-plus-blocking-requests-to-sentry-and-monitoring
Nov 24, 2025
Merged

fix(nextjs): universal random tunnel path support#18257
logaretm merged 16 commits into
developfrom
awad/js-549-adblock-plus-blocking-requests-to-sentry-and-monitoring

Conversation

@logaretm

@logaretmlogaretm commented Nov 19, 2025

Copy link
Copy Markdown
Member

When using Next.js with Turbopack and the Sentry tunnel route feature (tunnelRoute: true), several issues prevented events from being sent properly:

1. Tunnel Route Consistency (Turbopack)

Problem: Random tunnel routes were generated separately for client and server builds in Turbopack.

Solution: Implemented processs-level caching in withSentryConfig.ts:

  • Extract tunnel route resolution into resolveTunnelRoute() function
  • Use process.env to store the random tunnel value across server/client builds.

2. Filter Tunnel Request Spans

Problem: Requests to the tunnel route (before rewrite) and to Sentry ingest URLs (after rewrite) were creating spans that polluted Sentry with internal instrumentation noise, spans were being created by the middleware and OTEL node.js fetch instrumentation.

Solution: Implemented server-side span filtering:

  • Created dropMiddlewareTunnelRequests() utility to detect and drop tunnel-related spans
  • Filter spans originating from Middleware.execute (Next.js middleware)
  • Filter spans originating from auto.http.otel.node_fetch (Node.js fetch instrumentation)
  • Check both local tunnel paths and Sentry ingest URLs (using isSentryRequestSpan from @sentry/opentelemetry)
  • Mark matching spans with TRANSACTION_ATTR_SHOULD_DROP_TRANSACTION to prevent them from being sent
  • I tried beforeSampling hook but it didn't work for some reason, so I stuck with the drop attribute.

The final issue was excluding the tunnel requests from the middleware/proxy, but there are many blockers for a solution:

  1. The config must be statically analyzable, so we cannot expose withSentryMiddlewareConfig wrapper of any kind.
  2. Warning the user doesn't help much because they can't do anything about it since the tunnel route is random.
  3. Tested out writing a loader for turbopack/webpack to inject the tunnel into the matcher as an array but user existing matcher can match still.
  4. Only way is to inject an exclusion match into the user existing matcher, if it is an array then we need to inject it into each single entry.

I may explore this further later with a loader for both webpack/turbopack, and figure out a reliable way to inject the negative matchers into the user expressions.

@linear

linearBot commented Nov 19, 2025

Copy link
Copy Markdown

@logaretmlogaretm changed the title fix(nextjs): Turbopack random tunnel supportfix(nextjs): Turbopack random tunnel path supportNov 19, 2025
@logaretm
logaretmforce-pushed the awad/js-549-adblock-plus-blocking-requests-to-sentry-and-monitoring branch from a230c8b to dd615c6CompareNovember 20, 2025 09:37
@github-actions

github-actionsBot commented Nov 20, 2025

Copy link
Copy Markdown
Contributor

size-limit report 📦

PathSize% ChangeChange
@sentry/browser24.7 kB--
@sentry/browser - with treeshaking flags23.2 kB--
@sentry/browser (incl. Tracing)41.43 kB--
@sentry/browser (incl. Tracing, Profiling)45.75 kB--
@sentry/browser (incl. Tracing, Replay)79.85 kB--
@sentry/browser (incl. Tracing, Replay) - with treeshaking flags69.57 kB--
@sentry/browser (incl. Tracing, Replay with Canvas)84.55 kB--
@sentry/browser (incl. Tracing, Replay, Feedback)96.77 kB--
@sentry/browser (incl. Feedback)41.38 kB--
@sentry/browser (incl. sendFeedback)29.39 kB--
@sentry/browser (incl. FeedbackAsync)34.33 kB--
@sentry/react26.41 kB--
@sentry/react (incl. Tracing)43.43 kB--
@sentry/vue29.15 kB--
@sentry/vue (incl. Tracing)43.23 kB--
@sentry/svelte24.72 kB--
CDN Bundle27.02 kB--
CDN Bundle (incl. Tracing)42.02 kB--
CDN Bundle (incl. Tracing, Replay)78.53 kB--
CDN Bundle (incl. Tracing, Replay, Feedback)84.02 kB--
CDN Bundle - uncompressed79.17 kB--
CDN Bundle (incl. Tracing) - uncompressed124.55 kB--
CDN Bundle (incl. Tracing, Replay) - uncompressed240.59 kB--
CDN Bundle (incl. Tracing, Replay, Feedback) - uncompressed253.35 kB--
@sentry/nextjs (client)45.84 kB--
@sentry/sveltekit (client)41.79 kB--
@sentry/node-core51.02 kB--
@sentry/node159.34 kB--
@sentry/node - without tracing92.88 kB-0.03%-19 B 🔽
@sentry/aws-serverless106.64 kB--

View base workflow run

@logaretm
logaretmforce-pushed the awad/js-549-adblock-plus-blocking-requests-to-sentry-and-monitoring branch from 795af30 to f787df1CompareNovember 20, 2025 15:56
@logaretmlogaretm changed the title fix(nextjs): Turbopack random tunnel path supportfix(nextjs): universal random tunnel path supportNov 21, 2025
@github-actions

github-actionsBot commented Nov 21, 2025

Copy link
Copy Markdown
Contributor

node-overhead report 🧳

Note: This is a synthetic benchmark with a minimal express app and does not necessarily reflect the real-world performance impact in an application.

ScenarioRequests/s% of BaselinePrev. Requests/sChange %
GET Baseline8,807-8,853-1%
GET With Sentry1,63219%1,777-8%
GET With Sentry (error only)6,05669%6,031+0%
POST Baseline1,191-1,207-1%
POST With Sentry59450%597-1%
POST With Sentry (error only)1,03287%1,060-3%
MYSQL Baseline3,190-3,301-3%
MYSQL With Sentry42113%490-14%
MYSQL With Sentry (error only)2,61582%2,724-4%

View base workflow run

@logaretm
logaretmforce-pushed the awad/js-549-adblock-plus-blocking-requests-to-sentry-and-monitoring branch from 4fab2f0 to 856a4d1CompareNovember 21, 2025 11:26
@logaretm
logaretm marked this pull request as ready for review November 21, 2025 11:26
@logaretm
logaretmforce-pushed the awad/js-549-adblock-plus-blocking-requests-to-sentry-and-monitoring branch from d5442a6 to b332e39CompareNovember 21, 2025 13:11
@logaretm
logaretmforce-pushed the awad/js-549-adblock-plus-blocking-requests-to-sentry-and-monitoring branch from b332e39 to 981121cCompareNovember 21, 2025 13:12
}) satisfies EventProcessor,
{ id: 'NextLowQualityTransactionsFilter' },
),
);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Bug: Edge runtime missing tunnel route transaction filter

The event processor on the edge runtime only filters transactions based on the TRANSACTION_ATTR_SHOULD_DROP_TRANSACTION attribute, but lacks the explicit tunnel route transaction name check present in the server-side event processor. This asymmetry creates a defensive gap: if span marking fails for any reason, server-side transactions are still filtered by name, but edge-side transactions would slip through. For consistency and robustness, the edge-side event processor should include the same explicit tunnel route check that filters POST requests to the tunnel path.

Fix in CursorFix in Web

// env works well here
// https://linear.app/getsentry/issue/JS-549/adblock-plus-blocking-requests-to-sentry-and-monitoring-tunnel
if (resolvedTunnelRoute) {
process.env.__SENTRY_TUNNEL_ROUTE__ = resolvedTunnelRoute;

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.

Nice find!

@logaretm
logaretm merged commit 4b92c64 into developNov 24, 2025
66 checks passed
@logaretm
logaretm deleted the awad/js-549-adblock-plus-blocking-requests-to-sentry-and-monitoring branch November 24, 2025 15:41
Sign up for freeto 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.

3 participants

@logaretm@chargome@github-advanced-security
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

fix(nextjs): universal random tunnel path support - #18257

Merged
logaretm merged 16 commits into
developfrom
awad/js-549-adblock-plus-blocking-requests-to-sentry-and-monitoring
Nov 24, 2025
Merged

fix(nextjs): universal random tunnel path support#18257
logaretm merged 16 commits into
developfrom
awad/js-549-adblock-plus-blocking-requests-to-sentry-and-monitoring

Conversation

@logaretm

@logaretmlogaretm commented Nov 19, 2025

Copy link
Copy Markdown
Member

When using Next.js with Turbopack and the Sentry tunnel route feature (tunnelRoute: true), several issues prevented events from being sent properly:

1. Tunnel Route Consistency (Turbopack)

Problem: Random tunnel routes were generated separately for client and server builds in Turbopack.

Solution: Implemented processs-level caching in withSentryConfig.ts:

  • Extract tunnel route resolution into resolveTunnelRoute() function
  • Use process.env to store the random tunnel value across server/client builds.

2. Filter Tunnel Request Spans

Problem: Requests to the tunnel route (before rewrite) and to Sentry ingest URLs (after rewrite) were creating spans that polluted Sentry with internal instrumentation noise, spans were being created by the middleware and OTEL node.js fetch instrumentation.

Solution: Implemented server-side span filtering:

  • Created dropMiddlewareTunnelRequests() utility to detect and drop tunnel-related spans
  • Filter spans originating from Middleware.execute (Next.js middleware)
  • Filter spans originating from auto.http.otel.node_fetch (Node.js fetch instrumentation)
  • Check both local tunnel paths and Sentry ingest URLs (using isSentryRequestSpan from @sentry/opentelemetry)
  • Mark matching spans with TRANSACTION_ATTR_SHOULD_DROP_TRANSACTION to prevent them from being sent
  • I tried beforeSampling hook but it didn't work for some reason, so I stuck with the drop attribute.

The final issue was excluding the tunnel requests from the middleware/proxy, but there are many blockers for a solution:

  1. The config must be statically analyzable, so we cannot expose withSentryMiddlewareConfig wrapper of any kind.
  2. Warning the user doesn't help much because they can't do anything about it since the tunnel route is random.
  3. Tested out writing a loader for turbopack/webpack to inject the tunnel into the matcher as an array but user existing matcher can match still.
  4. Only way is to inject an exclusion match into the user existing matcher, if it is an array then we need to inject it into each single entry.

I may explore this further later with a loader for both webpack/turbopack, and figure out a reliable way to inject the negative matchers into the user expressions.

@linear

linearBot commented Nov 19, 2025

Copy link
Copy Markdown

@logaretmlogaretm changed the title fix(nextjs): Turbopack random tunnel supportfix(nextjs): Turbopack random tunnel path supportNov 19, 2025
@logaretm
logaretmforce-pushed the awad/js-549-adblock-plus-blocking-requests-to-sentry-and-monitoring branch from a230c8b to dd615c6CompareNovember 20, 2025 09:37
@github-actions

github-actionsBot commented Nov 20, 2025

Copy link
Copy Markdown
Contributor

size-limit report 📦

PathSize% ChangeChange
@sentry/browser24.7 kB--
@sentry/browser - with treeshaking flags23.2 kB--
@sentry/browser (incl. Tracing)41.43 kB--
@sentry/browser (incl. Tracing, Profiling)45.75 kB--
@sentry/browser (incl. Tracing, Replay)79.85 kB--
@sentry/browser (incl. Tracing, Replay) - with treeshaking flags69.57 kB--
@sentry/browser (incl. Tracing, Replay with Canvas)84.55 kB--
@sentry/browser (incl. Tracing, Replay, Feedback)96.77 kB--
@sentry/browser (incl. Feedback)41.38 kB--
@sentry/browser (incl. sendFeedback)29.39 kB--
@sentry/browser (incl. FeedbackAsync)34.33 kB--
@sentry/react26.41 kB--
@sentry/react (incl. Tracing)43.43 kB--
@sentry/vue29.15 kB--
@sentry/vue (incl. Tracing)43.23 kB--
@sentry/svelte24.72 kB--
CDN Bundle27.02 kB--
CDN Bundle (incl. Tracing)42.02 kB--
CDN Bundle (incl. Tracing, Replay)78.53 kB--
CDN Bundle (incl. Tracing, Replay, Feedback)84.02 kB--
CDN Bundle - uncompressed79.17 kB--
CDN Bundle (incl. Tracing) - uncompressed124.55 kB--
CDN Bundle (incl. Tracing, Replay) - uncompressed240.59 kB--
CDN Bundle (incl. Tracing, Replay, Feedback) - uncompressed253.35 kB--
@sentry/nextjs (client)45.84 kB--
@sentry/sveltekit (client)41.79 kB--
@sentry/node-core51.02 kB--
@sentry/node159.34 kB--
@sentry/node - without tracing92.88 kB-0.03%-19 B 🔽
@sentry/aws-serverless106.64 kB--

View base workflow run

@logaretm
logaretmforce-pushed the awad/js-549-adblock-plus-blocking-requests-to-sentry-and-monitoring branch from 795af30 to f787df1CompareNovember 20, 2025 15:56
@logaretmlogaretm changed the title fix(nextjs): Turbopack random tunnel path supportfix(nextjs): universal random tunnel path supportNov 21, 2025
@github-actions

github-actionsBot commented Nov 21, 2025

Copy link
Copy Markdown
Contributor

node-overhead report 🧳

Note: This is a synthetic benchmark with a minimal express app and does not necessarily reflect the real-world performance impact in an application.

ScenarioRequests/s% of BaselinePrev. Requests/sChange %
GET Baseline8,807-8,853-1%
GET With Sentry1,63219%1,777-8%
GET With Sentry (error only)6,05669%6,031+0%
POST Baseline1,191-1,207-1%
POST With Sentry59450%597-1%
POST With Sentry (error only)1,03287%1,060-3%
MYSQL Baseline3,190-3,301-3%
MYSQL With Sentry42113%490-14%
MYSQL With Sentry (error only)2,61582%2,724-4%

View base workflow run

@logaretm
logaretmforce-pushed the awad/js-549-adblock-plus-blocking-requests-to-sentry-and-monitoring branch from 4fab2f0 to 856a4d1CompareNovember 21, 2025 11:26
@logaretm
logaretm marked this pull request as ready for review November 21, 2025 11:26
@logaretm
logaretmforce-pushed the awad/js-549-adblock-plus-blocking-requests-to-sentry-and-monitoring branch from d5442a6 to b332e39CompareNovember 21, 2025 13:11
@logaretm
logaretmforce-pushed the awad/js-549-adblock-plus-blocking-requests-to-sentry-and-monitoring branch from b332e39 to 981121cCompareNovember 21, 2025 13:12
}) satisfies EventProcessor,
{ id: 'NextLowQualityTransactionsFilter' },
),
);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Bug: Edge runtime missing tunnel route transaction filter

The event processor on the edge runtime only filters transactions based on the TRANSACTION_ATTR_SHOULD_DROP_TRANSACTION attribute, but lacks the explicit tunnel route transaction name check present in the server-side event processor. This asymmetry creates a defensive gap: if span marking fails for any reason, server-side transactions are still filtered by name, but edge-side transactions would slip through. For consistency and robustness, the edge-side event processor should include the same explicit tunnel route check that filters POST requests to the tunnel path.

Fix in CursorFix in Web

// env works well here
// https://linear.app/getsentry/issue/JS-549/adblock-plus-blocking-requests-to-sentry-and-monitoring-tunnel
if (resolvedTunnelRoute) {
process.env.__SENTRY_TUNNEL_ROUTE__ = resolvedTunnelRoute;

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.

Nice find!

@logaretm
logaretm merged commit 4b92c64 into developNov 24, 2025
66 checks passed
@logaretm
logaretm deleted the awad/js-549-adblock-plus-blocking-requests-to-sentry-and-monitoring branch November 24, 2025 15:41
Sign up for freeto 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.

3 participants

@logaretm@chargome@github-advanced-security
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

fix(nextjs): universal random tunnel path support - #18257

Merged
logaretm merged 16 commits into
developfrom
awad/js-549-adblock-plus-blocking-requests-to-sentry-and-monitoring
Nov 24, 2025
Merged

fix(nextjs): universal random tunnel path support#18257
logaretm merged 16 commits into
developfrom
awad/js-549-adblock-plus-blocking-requests-to-sentry-and-monitoring

Conversation

@logaretm

@logaretmlogaretm commented Nov 19, 2025

Copy link
Copy Markdown
Member

When using Next.js with Turbopack and the Sentry tunnel route feature (tunnelRoute: true), several issues prevented events from being sent properly:

1. Tunnel Route Consistency (Turbopack)

Problem: Random tunnel routes were generated separately for client and server builds in Turbopack.

Solution: Implemented processs-level caching in withSentryConfig.ts:

  • Extract tunnel route resolution into resolveTunnelRoute() function
  • Use process.env to store the random tunnel value across server/client builds.

2. Filter Tunnel Request Spans

Problem: Requests to the tunnel route (before rewrite) and to Sentry ingest URLs (after rewrite) were creating spans that polluted Sentry with internal instrumentation noise, spans were being created by the middleware and OTEL node.js fetch instrumentation.

Solution: Implemented server-side span filtering:

  • Created dropMiddlewareTunnelRequests() utility to detect and drop tunnel-related spans
  • Filter spans originating from Middleware.execute (Next.js middleware)
  • Filter spans originating from auto.http.otel.node_fetch (Node.js fetch instrumentation)
  • Check both local tunnel paths and Sentry ingest URLs (using isSentryRequestSpan from @sentry/opentelemetry)
  • Mark matching spans with TRANSACTION_ATTR_SHOULD_DROP_TRANSACTION to prevent them from being sent
  • I tried beforeSampling hook but it didn't work for some reason, so I stuck with the drop attribute.

The final issue was excluding the tunnel requests from the middleware/proxy, but there are many blockers for a solution:

  1. The config must be statically analyzable, so we cannot expose withSentryMiddlewareConfig wrapper of any kind.
  2. Warning the user doesn't help much because they can't do anything about it since the tunnel route is random.
  3. Tested out writing a loader for turbopack/webpack to inject the tunnel into the matcher as an array but user existing matcher can match still.
  4. Only way is to inject an exclusion match into the user existing matcher, if it is an array then we need to inject it into each single entry.

I may explore this further later with a loader for both webpack/turbopack, and figure out a reliable way to inject the negative matchers into the user expressions.

@linear

linearBot commented Nov 19, 2025

Copy link
Copy Markdown

@logaretmlogaretm changed the title fix(nextjs): Turbopack random tunnel supportfix(nextjs): Turbopack random tunnel path supportNov 19, 2025
@logaretm
logaretmforce-pushed the awad/js-549-adblock-plus-blocking-requests-to-sentry-and-monitoring branch from a230c8b to dd615c6CompareNovember 20, 2025 09:37
@github-actions

github-actionsBot commented Nov 20, 2025

Copy link
Copy Markdown
Contributor

size-limit report 📦

PathSize% ChangeChange
@sentry/browser24.7 kB--
@sentry/browser - with treeshaking flags23.2 kB--
@sentry/browser (incl. Tracing)41.43 kB--
@sentry/browser (incl. Tracing, Profiling)45.75 kB--
@sentry/browser (incl. Tracing, Replay)79.85 kB--
@sentry/browser (incl. Tracing, Replay) - with treeshaking flags69.57 kB--
@sentry/browser (incl. Tracing, Replay with Canvas)84.55 kB--
@sentry/browser (incl. Tracing, Replay, Feedback)96.77 kB--
@sentry/browser (incl. Feedback)41.38 kB--
@sentry/browser (incl. sendFeedback)29.39 kB--
@sentry/browser (incl. FeedbackAsync)34.33 kB--
@sentry/react26.41 kB--
@sentry/react (incl. Tracing)43.43 kB--
@sentry/vue29.15 kB--
@sentry/vue (incl. Tracing)43.23 kB--
@sentry/svelte24.72 kB--
CDN Bundle27.02 kB--
CDN Bundle (incl. Tracing)42.02 kB--
CDN Bundle (incl. Tracing, Replay)78.53 kB--
CDN Bundle (incl. Tracing, Replay, Feedback)84.02 kB--
CDN Bundle - uncompressed79.17 kB--
CDN Bundle (incl. Tracing) - uncompressed124.55 kB--
CDN Bundle (incl. Tracing, Replay) - uncompressed240.59 kB--
CDN Bundle (incl. Tracing, Replay, Feedback) - uncompressed253.35 kB--
@sentry/nextjs (client)45.84 kB--
@sentry/sveltekit (client)41.79 kB--
@sentry/node-core51.02 kB--
@sentry/node159.34 kB--
@sentry/node - without tracing92.88 kB-0.03%-19 B 🔽
@sentry/aws-serverless106.64 kB--

View base workflow run

@logaretm
logaretmforce-pushed the awad/js-549-adblock-plus-blocking-requests-to-sentry-and-monitoring branch from 795af30 to f787df1CompareNovember 20, 2025 15:56
@logaretmlogaretm changed the title fix(nextjs): Turbopack random tunnel path supportfix(nextjs): universal random tunnel path supportNov 21, 2025
@github-actions

github-actionsBot commented Nov 21, 2025

Copy link
Copy Markdown
Contributor

node-overhead report 🧳

Note: This is a synthetic benchmark with a minimal express app and does not necessarily reflect the real-world performance impact in an application.

ScenarioRequests/s% of BaselinePrev. Requests/sChange %
GET Baseline8,807-8,853-1%
GET With Sentry1,63219%1,777-8%
GET With Sentry (error only)6,05669%6,031+0%
POST Baseline1,191-1,207-1%
POST With Sentry59450%597-1%
POST With Sentry (error only)1,03287%1,060-3%
MYSQL Baseline3,190-3,301-3%
MYSQL With Sentry42113%490-14%
MYSQL With Sentry (error only)2,61582%2,724-4%

View base workflow run

@logaretm
logaretmforce-pushed the awad/js-549-adblock-plus-blocking-requests-to-sentry-and-monitoring branch from 4fab2f0 to 856a4d1CompareNovember 21, 2025 11:26
@logaretm
logaretm marked this pull request as ready for review November 21, 2025 11:26
@logaretm
logaretmforce-pushed the awad/js-549-adblock-plus-blocking-requests-to-sentry-and-monitoring branch from d5442a6 to b332e39CompareNovember 21, 2025 13:11
@logaretm
logaretmforce-pushed the awad/js-549-adblock-plus-blocking-requests-to-sentry-and-monitoring branch from b332e39 to 981121cCompareNovember 21, 2025 13:12
}) satisfies EventProcessor,
{ id: 'NextLowQualityTransactionsFilter' },
),
);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Bug: Edge runtime missing tunnel route transaction filter

The event processor on the edge runtime only filters transactions based on the TRANSACTION_ATTR_SHOULD_DROP_TRANSACTION attribute, but lacks the explicit tunnel route transaction name check present in the server-side event processor. This asymmetry creates a defensive gap: if span marking fails for any reason, server-side transactions are still filtered by name, but edge-side transactions would slip through. For consistency and robustness, the edge-side event processor should include the same explicit tunnel route check that filters POST requests to the tunnel path.

Fix in CursorFix in Web

// env works well here
// https://linear.app/getsentry/issue/JS-549/adblock-plus-blocking-requests-to-sentry-and-monitoring-tunnel
if (resolvedTunnelRoute) {
process.env.__SENTRY_TUNNEL_ROUTE__ = resolvedTunnelRoute;

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.

Nice find!

@logaretm
logaretm merged commit 4b92c64 into developNov 24, 2025
66 checks passed
@logaretm
logaretm deleted the awad/js-549-adblock-plus-blocking-requests-to-sentry-and-monitoring branch November 24, 2025 15:41
Sign up for freeto 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.

3 participants

@logaretm@chargome@github-advanced-security
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

fix(nextjs): universal random tunnel path support - #18257

Merged
logaretm merged 16 commits into
developfrom
awad/js-549-adblock-plus-blocking-requests-to-sentry-and-monitoring
Nov 24, 2025
Merged

fix(nextjs): universal random tunnel path support#18257
logaretm merged 16 commits into
developfrom
awad/js-549-adblock-plus-blocking-requests-to-sentry-and-monitoring

Conversation

@logaretm

@logaretmlogaretm commented Nov 19, 2025

Copy link
Copy Markdown
Member

When using Next.js with Turbopack and the Sentry tunnel route feature (tunnelRoute: true), several issues prevented events from being sent properly:

1. Tunnel Route Consistency (Turbopack)

Problem: Random tunnel routes were generated separately for client and server builds in Turbopack.

Solution: Implemented processs-level caching in withSentryConfig.ts:

  • Extract tunnel route resolution into resolveTunnelRoute() function
  • Use process.env to store the random tunnel value across server/client builds.

2. Filter Tunnel Request Spans

Problem: Requests to the tunnel route (before rewrite) and to Sentry ingest URLs (after rewrite) were creating spans that polluted Sentry with internal instrumentation noise, spans were being created by the middleware and OTEL node.js fetch instrumentation.

Solution: Implemented server-side span filtering:

  • Created dropMiddlewareTunnelRequests() utility to detect and drop tunnel-related spans
  • Filter spans originating from Middleware.execute (Next.js middleware)
  • Filter spans originating from auto.http.otel.node_fetch (Node.js fetch instrumentation)
  • Check both local tunnel paths and Sentry ingest URLs (using isSentryRequestSpan from @sentry/opentelemetry)
  • Mark matching spans with TRANSACTION_ATTR_SHOULD_DROP_TRANSACTION to prevent them from being sent
  • I tried beforeSampling hook but it didn't work for some reason, so I stuck with the drop attribute.

The final issue was excluding the tunnel requests from the middleware/proxy, but there are many blockers for a solution:

  1. The config must be statically analyzable, so we cannot expose withSentryMiddlewareConfig wrapper of any kind.
  2. Warning the user doesn't help much because they can't do anything about it since the tunnel route is random.
  3. Tested out writing a loader for turbopack/webpack to inject the tunnel into the matcher as an array but user existing matcher can match still.
  4. Only way is to inject an exclusion match into the user existing matcher, if it is an array then we need to inject it into each single entry.

I may explore this further later with a loader for both webpack/turbopack, and figure out a reliable way to inject the negative matchers into the user expressions.

@linear

linearBot commented Nov 19, 2025

Copy link
Copy Markdown

@logaretmlogaretm changed the title fix(nextjs): Turbopack random tunnel supportfix(nextjs): Turbopack random tunnel path supportNov 19, 2025
@logaretm
logaretmforce-pushed the awad/js-549-adblock-plus-blocking-requests-to-sentry-and-monitoring branch from a230c8b to dd615c6CompareNovember 20, 2025 09:37
@github-actions

github-actionsBot commented Nov 20, 2025

Copy link
Copy Markdown
Contributor

size-limit report 📦

PathSize% ChangeChange
@sentry/browser24.7 kB--
@sentry/browser - with treeshaking flags23.2 kB--
@sentry/browser (incl. Tracing)41.43 kB--
@sentry/browser (incl. Tracing, Profiling)45.75 kB--
@sentry/browser (incl. Tracing, Replay)79.85 kB--
@sentry/browser (incl. Tracing, Replay) - with treeshaking flags69.57 kB--
@sentry/browser (incl. Tracing, Replay with Canvas)84.55 kB--
@sentry/browser (incl. Tracing, Replay, Feedback)96.77 kB--
@sentry/browser (incl. Feedback)41.38 kB--
@sentry/browser (incl. sendFeedback)29.39 kB--
@sentry/browser (incl. FeedbackAsync)34.33 kB--
@sentry/react26.41 kB--
@sentry/react (incl. Tracing)43.43 kB--
@sentry/vue29.15 kB--
@sentry/vue (incl. Tracing)43.23 kB--
@sentry/svelte24.72 kB--
CDN Bundle27.02 kB--
CDN Bundle (incl. Tracing)42.02 kB--
CDN Bundle (incl. Tracing, Replay)78.53 kB--
CDN Bundle (incl. Tracing, Replay, Feedback)84.02 kB--
CDN Bundle - uncompressed79.17 kB--
CDN Bundle (incl. Tracing) - uncompressed124.55 kB--
CDN Bundle (incl. Tracing, Replay) - uncompressed240.59 kB--
CDN Bundle (incl. Tracing, Replay, Feedback) - uncompressed253.35 kB--
@sentry/nextjs (client)45.84 kB--
@sentry/sveltekit (client)41.79 kB--
@sentry/node-core51.02 kB--
@sentry/node159.34 kB--
@sentry/node - without tracing92.88 kB-0.03%-19 B 🔽
@sentry/aws-serverless106.64 kB--

View base workflow run

@logaretm
logaretmforce-pushed the awad/js-549-adblock-plus-blocking-requests-to-sentry-and-monitoring branch from 795af30 to f787df1CompareNovember 20, 2025 15:56
@logaretmlogaretm changed the title fix(nextjs): Turbopack random tunnel path supportfix(nextjs): universal random tunnel path supportNov 21, 2025
@github-actions

github-actionsBot commented Nov 21, 2025

Copy link
Copy Markdown
Contributor

node-overhead report 🧳

Note: This is a synthetic benchmark with a minimal express app and does not necessarily reflect the real-world performance impact in an application.

ScenarioRequests/s% of BaselinePrev. Requests/sChange %
GET Baseline8,807-8,853-1%
GET With Sentry1,63219%1,777-8%
GET With Sentry (error only)6,05669%6,031+0%
POST Baseline1,191-1,207-1%
POST With Sentry59450%597-1%
POST With Sentry (error only)1,03287%1,060-3%
MYSQL Baseline3,190-3,301-3%
MYSQL With Sentry42113%490-14%
MYSQL With Sentry (error only)2,61582%2,724-4%

View base workflow run

@logaretm
logaretmforce-pushed the awad/js-549-adblock-plus-blocking-requests-to-sentry-and-monitoring branch from 4fab2f0 to 856a4d1CompareNovember 21, 2025 11:26
@logaretm
logaretm marked this pull request as ready for review November 21, 2025 11:26
@logaretm
logaretmforce-pushed the awad/js-549-adblock-plus-blocking-requests-to-sentry-and-monitoring branch from d5442a6 to b332e39CompareNovember 21, 2025 13:11
@logaretm
logaretmforce-pushed the awad/js-549-adblock-plus-blocking-requests-to-sentry-and-monitoring branch from b332e39 to 981121cCompareNovember 21, 2025 13:12
}) satisfies EventProcessor,
{ id: 'NextLowQualityTransactionsFilter' },
),
);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Bug: Edge runtime missing tunnel route transaction filter

The event processor on the edge runtime only filters transactions based on the TRANSACTION_ATTR_SHOULD_DROP_TRANSACTION attribute, but lacks the explicit tunnel route transaction name check present in the server-side event processor. This asymmetry creates a defensive gap: if span marking fails for any reason, server-side transactions are still filtered by name, but edge-side transactions would slip through. For consistency and robustness, the edge-side event processor should include the same explicit tunnel route check that filters POST requests to the tunnel path.

Fix in CursorFix in Web

// env works well here
// https://linear.app/getsentry/issue/JS-549/adblock-plus-blocking-requests-to-sentry-and-monitoring-tunnel
if (resolvedTunnelRoute) {
process.env.__SENTRY_TUNNEL_ROUTE__ = resolvedTunnelRoute;

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.

Nice find!

@logaretm
logaretm merged commit 4b92c64 into developNov 24, 2025
66 checks passed
@logaretm
logaretm deleted the awad/js-549-adblock-plus-blocking-requests-to-sentry-and-monitoring branch November 24, 2025 15:41
Sign up for freeto 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.

3 participants

@logaretm@chargome@github-advanced-security
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

fix(nextjs): universal random tunnel path support - #18257

Merged
logaretm merged 16 commits into
developfrom
awad/js-549-adblock-plus-blocking-requests-to-sentry-and-monitoring
Nov 24, 2025
Merged

fix(nextjs): universal random tunnel path support#18257
logaretm merged 16 commits into
developfrom
awad/js-549-adblock-plus-blocking-requests-to-sentry-and-monitoring

Conversation

@logaretm

@logaretmlogaretm commented Nov 19, 2025

Copy link
Copy Markdown
Member

When using Next.js with Turbopack and the Sentry tunnel route feature (tunnelRoute: true), several issues prevented events from being sent properly:

1. Tunnel Route Consistency (Turbopack)

Problem: Random tunnel routes were generated separately for client and server builds in Turbopack.

Solution: Implemented processs-level caching in withSentryConfig.ts:

  • Extract tunnel route resolution into resolveTunnelRoute() function
  • Use process.env to store the random tunnel value across server/client builds.

2. Filter Tunnel Request Spans

Problem: Requests to the tunnel route (before rewrite) and to Sentry ingest URLs (after rewrite) were creating spans that polluted Sentry with internal instrumentation noise, spans were being created by the middleware and OTEL node.js fetch instrumentation.

Solution: Implemented server-side span filtering:

  • Created dropMiddlewareTunnelRequests() utility to detect and drop tunnel-related spans
  • Filter spans originating from Middleware.execute (Next.js middleware)
  • Filter spans originating from auto.http.otel.node_fetch (Node.js fetch instrumentation)
  • Check both local tunnel paths and Sentry ingest URLs (using isSentryRequestSpan from @sentry/opentelemetry)
  • Mark matching spans with TRANSACTION_ATTR_SHOULD_DROP_TRANSACTION to prevent them from being sent
  • I tried beforeSampling hook but it didn't work for some reason, so I stuck with the drop attribute.

The final issue was excluding the tunnel requests from the middleware/proxy, but there are many blockers for a solution:

  1. The config must be statically analyzable, so we cannot expose withSentryMiddlewareConfig wrapper of any kind.
  2. Warning the user doesn't help much because they can't do anything about it since the tunnel route is random.
  3. Tested out writing a loader for turbopack/webpack to inject the tunnel into the matcher as an array but user existing matcher can match still.
  4. Only way is to inject an exclusion match into the user existing matcher, if it is an array then we need to inject it into each single entry.

I may explore this further later with a loader for both webpack/turbopack, and figure out a reliable way to inject the negative matchers into the user expressions.

@linear

linearBot commented Nov 19, 2025

Copy link
Copy Markdown

@logaretmlogaretm changed the title fix(nextjs): Turbopack random tunnel supportfix(nextjs): Turbopack random tunnel path supportNov 19, 2025
@logaretm
logaretmforce-pushed the awad/js-549-adblock-plus-blocking-requests-to-sentry-and-monitoring branch from a230c8b to dd615c6CompareNovember 20, 2025 09:37
@github-actions

github-actionsBot commented Nov 20, 2025

Copy link
Copy Markdown
Contributor

size-limit report 📦

PathSize% ChangeChange
@sentry/browser24.7 kB--
@sentry/browser - with treeshaking flags23.2 kB--
@sentry/browser (incl. Tracing)41.43 kB--
@sentry/browser (incl. Tracing, Profiling)45.75 kB--
@sentry/browser (incl. Tracing, Replay)79.85 kB--
@sentry/browser (incl. Tracing, Replay) - with treeshaking flags69.57 kB--
@sentry/browser (incl. Tracing, Replay with Canvas)84.55 kB--
@sentry/browser (incl. Tracing, Replay, Feedback)96.77 kB--
@sentry/browser (incl. Feedback)41.38 kB--
@sentry/browser (incl. sendFeedback)29.39 kB--
@sentry/browser (incl. FeedbackAsync)34.33 kB--
@sentry/react26.41 kB--
@sentry/react (incl. Tracing)43.43 kB--
@sentry/vue29.15 kB--
@sentry/vue (incl. Tracing)43.23 kB--
@sentry/svelte24.72 kB--
CDN Bundle27.02 kB--
CDN Bundle (incl. Tracing)42.02 kB--
CDN Bundle (incl. Tracing, Replay)78.53 kB--
CDN Bundle (incl. Tracing, Replay, Feedback)84.02 kB--
CDN Bundle - uncompressed79.17 kB--
CDN Bundle (incl. Tracing) - uncompressed124.55 kB--
CDN Bundle (incl. Tracing, Replay) - uncompressed240.59 kB--
CDN Bundle (incl. Tracing, Replay, Feedback) - uncompressed253.35 kB--
@sentry/nextjs (client)45.84 kB--
@sentry/sveltekit (client)41.79 kB--
@sentry/node-core51.02 kB--
@sentry/node159.34 kB--
@sentry/node - without tracing92.88 kB-0.03%-19 B 🔽
@sentry/aws-serverless106.64 kB--

View base workflow run

@logaretm
logaretmforce-pushed the awad/js-549-adblock-plus-blocking-requests-to-sentry-and-monitoring branch from 795af30 to f787df1CompareNovember 20, 2025 15:56
@logaretmlogaretm changed the title fix(nextjs): Turbopack random tunnel path supportfix(nextjs): universal random tunnel path supportNov 21, 2025
@github-actions

github-actionsBot commented Nov 21, 2025

Copy link
Copy Markdown
Contributor

node-overhead report 🧳

Note: This is a synthetic benchmark with a minimal express app and does not necessarily reflect the real-world performance impact in an application.

ScenarioRequests/s% of BaselinePrev. Requests/sChange %
GET Baseline8,807-8,853-1%
GET With Sentry1,63219%1,777-8%
GET With Sentry (error only)6,05669%6,031+0%
POST Baseline1,191-1,207-1%
POST With Sentry59450%597-1%
POST With Sentry (error only)1,03287%1,060-3%
MYSQL Baseline3,190-3,301-3%
MYSQL With Sentry42113%490-14%
MYSQL With Sentry (error only)2,61582%2,724-4%

View base workflow run

@logaretm
logaretmforce-pushed the awad/js-549-adblock-plus-blocking-requests-to-sentry-and-monitoring branch from 4fab2f0 to 856a4d1CompareNovember 21, 2025 11:26
@logaretm
logaretm marked this pull request as ready for review November 21, 2025 11:26
@logaretm
logaretmforce-pushed the awad/js-549-adblock-plus-blocking-requests-to-sentry-and-monitoring branch from d5442a6 to b332e39CompareNovember 21, 2025 13:11
@logaretm
logaretmforce-pushed the awad/js-549-adblock-plus-blocking-requests-to-sentry-and-monitoring branch from b332e39 to 981121cCompareNovember 21, 2025 13:12
}) satisfies EventProcessor,
{ id: 'NextLowQualityTransactionsFilter' },
),
);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Bug: Edge runtime missing tunnel route transaction filter

The event processor on the edge runtime only filters transactions based on the TRANSACTION_ATTR_SHOULD_DROP_TRANSACTION attribute, but lacks the explicit tunnel route transaction name check present in the server-side event processor. This asymmetry creates a defensive gap: if span marking fails for any reason, server-side transactions are still filtered by name, but edge-side transactions would slip through. For consistency and robustness, the edge-side event processor should include the same explicit tunnel route check that filters POST requests to the tunnel path.

Fix in CursorFix in Web

// env works well here
// https://linear.app/getsentry/issue/JS-549/adblock-plus-blocking-requests-to-sentry-and-monitoring-tunnel
if (resolvedTunnelRoute) {
process.env.__SENTRY_TUNNEL_ROUTE__ = resolvedTunnelRoute;

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.

Nice find!

@logaretm
logaretm merged commit 4b92c64 into developNov 24, 2025
66 checks passed
@logaretm
logaretm deleted the awad/js-549-adblock-plus-blocking-requests-to-sentry-and-monitoring branch November 24, 2025 15:41
Sign up for freeto 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.

3 participants

@logaretm@chargome@github-advanced-security
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

fix(nextjs): universal random tunnel path support - #18257

Merged
logaretm merged 16 commits into
developfrom
awad/js-549-adblock-plus-blocking-requests-to-sentry-and-monitoring
Nov 24, 2025
Merged

fix(nextjs): universal random tunnel path support#18257
logaretm merged 16 commits into
developfrom
awad/js-549-adblock-plus-blocking-requests-to-sentry-and-monitoring

Conversation

@logaretm

@logaretmlogaretm commented Nov 19, 2025

Copy link
Copy Markdown
Member

When using Next.js with Turbopack and the Sentry tunnel route feature (tunnelRoute: true), several issues prevented events from being sent properly:

1. Tunnel Route Consistency (Turbopack)

Problem: Random tunnel routes were generated separately for client and server builds in Turbopack.

Solution: Implemented processs-level caching in withSentryConfig.ts:

  • Extract tunnel route resolution into resolveTunnelRoute() function
  • Use process.env to store the random tunnel value across server/client builds.

2. Filter Tunnel Request Spans

Problem: Requests to the tunnel route (before rewrite) and to Sentry ingest URLs (after rewrite) were creating spans that polluted Sentry with internal instrumentation noise, spans were being created by the middleware and OTEL node.js fetch instrumentation.

Solution: Implemented server-side span filtering:

  • Created dropMiddlewareTunnelRequests() utility to detect and drop tunnel-related spans
  • Filter spans originating from Middleware.execute (Next.js middleware)
  • Filter spans originating from auto.http.otel.node_fetch (Node.js fetch instrumentation)
  • Check both local tunnel paths and Sentry ingest URLs (using isSentryRequestSpan from @sentry/opentelemetry)
  • Mark matching spans with TRANSACTION_ATTR_SHOULD_DROP_TRANSACTION to prevent them from being sent
  • I tried beforeSampling hook but it didn't work for some reason, so I stuck with the drop attribute.

The final issue was excluding the tunnel requests from the middleware/proxy, but there are many blockers for a solution:

  1. The config must be statically analyzable, so we cannot expose withSentryMiddlewareConfig wrapper of any kind.
  2. Warning the user doesn't help much because they can't do anything about it since the tunnel route is random.
  3. Tested out writing a loader for turbopack/webpack to inject the tunnel into the matcher as an array but user existing matcher can match still.
  4. Only way is to inject an exclusion match into the user existing matcher, if it is an array then we need to inject it into each single entry.

I may explore this further later with a loader for both webpack/turbopack, and figure out a reliable way to inject the negative matchers into the user expressions.

@linear

linearBot commented Nov 19, 2025

Copy link
Copy Markdown

@logaretmlogaretm changed the title fix(nextjs): Turbopack random tunnel supportfix(nextjs): Turbopack random tunnel path supportNov 19, 2025
@logaretm
logaretmforce-pushed the awad/js-549-adblock-plus-blocking-requests-to-sentry-and-monitoring branch from a230c8b to dd615c6CompareNovember 20, 2025 09:37
@github-actions

github-actionsBot commented Nov 20, 2025

Copy link
Copy Markdown
Contributor

size-limit report 📦

PathSize% ChangeChange
@sentry/browser24.7 kB--
@sentry/browser - with treeshaking flags23.2 kB--
@sentry/browser (incl. Tracing)41.43 kB--
@sentry/browser (incl. Tracing, Profiling)45.75 kB--
@sentry/browser (incl. Tracing, Replay)79.85 kB--
@sentry/browser (incl. Tracing, Replay) - with treeshaking flags69.57 kB--
@sentry/browser (incl. Tracing, Replay with Canvas)84.55 kB--
@sentry/browser (incl. Tracing, Replay, Feedback)96.77 kB--
@sentry/browser (incl. Feedback)41.38 kB--
@sentry/browser (incl. sendFeedback)29.39 kB--
@sentry/browser (incl. FeedbackAsync)34.33 kB--
@sentry/react26.41 kB--
@sentry/react (incl. Tracing)43.43 kB--
@sentry/vue29.15 kB--
@sentry/vue (incl. Tracing)43.23 kB--
@sentry/svelte24.72 kB--
CDN Bundle27.02 kB--
CDN Bundle (incl. Tracing)42.02 kB--
CDN Bundle (incl. Tracing, Replay)78.53 kB--
CDN Bundle (incl. Tracing, Replay, Feedback)84.02 kB--
CDN Bundle - uncompressed79.17 kB--
CDN Bundle (incl. Tracing) - uncompressed124.55 kB--
CDN Bundle (incl. Tracing, Replay) - uncompressed240.59 kB--
CDN Bundle (incl. Tracing, Replay, Feedback) - uncompressed253.35 kB--
@sentry/nextjs (client)45.84 kB--
@sentry/sveltekit (client)41.79 kB--
@sentry/node-core51.02 kB--
@sentry/node159.34 kB--
@sentry/node - without tracing92.88 kB-0.03%-19 B 🔽
@sentry/aws-serverless106.64 kB--

View base workflow run

@logaretm
logaretmforce-pushed the awad/js-549-adblock-plus-blocking-requests-to-sentry-and-monitoring branch from 795af30 to f787df1CompareNovember 20, 2025 15:56
@logaretmlogaretm changed the title fix(nextjs): Turbopack random tunnel path supportfix(nextjs): universal random tunnel path supportNov 21, 2025
@github-actions

github-actionsBot commented Nov 21, 2025

Copy link
Copy Markdown
Contributor

node-overhead report 🧳

Note: This is a synthetic benchmark with a minimal express app and does not necessarily reflect the real-world performance impact in an application.

ScenarioRequests/s% of BaselinePrev. Requests/sChange %
GET Baseline8,807-8,853-1%
GET With Sentry1,63219%1,777-8%
GET With Sentry (error only)6,05669%6,031+0%
POST Baseline1,191-1,207-1%
POST With Sentry59450%597-1%
POST With Sentry (error only)1,03287%1,060-3%
MYSQL Baseline3,190-3,301-3%
MYSQL With Sentry42113%490-14%
MYSQL With Sentry (error only)2,61582%2,724-4%

View base workflow run

@logaretm
logaretmforce-pushed the awad/js-549-adblock-plus-blocking-requests-to-sentry-and-monitoring branch from 4fab2f0 to 856a4d1CompareNovember 21, 2025 11:26
@logaretm
logaretm marked this pull request as ready for review November 21, 2025 11:26
@logaretm
logaretmforce-pushed the awad/js-549-adblock-plus-blocking-requests-to-sentry-and-monitoring branch from d5442a6 to b332e39CompareNovember 21, 2025 13:11
@logaretm
logaretmforce-pushed the awad/js-549-adblock-plus-blocking-requests-to-sentry-and-monitoring branch from b332e39 to 981121cCompareNovember 21, 2025 13:12
}) satisfies EventProcessor,
{ id: 'NextLowQualityTransactionsFilter' },
),
);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Bug: Edge runtime missing tunnel route transaction filter

The event processor on the edge runtime only filters transactions based on the TRANSACTION_ATTR_SHOULD_DROP_TRANSACTION attribute, but lacks the explicit tunnel route transaction name check present in the server-side event processor. This asymmetry creates a defensive gap: if span marking fails for any reason, server-side transactions are still filtered by name, but edge-side transactions would slip through. For consistency and robustness, the edge-side event processor should include the same explicit tunnel route check that filters POST requests to the tunnel path.

Fix in CursorFix in Web

// env works well here
// https://linear.app/getsentry/issue/JS-549/adblock-plus-blocking-requests-to-sentry-and-monitoring-tunnel
if (resolvedTunnelRoute) {
process.env.__SENTRY_TUNNEL_ROUTE__ = resolvedTunnelRoute;

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.

Nice find!

@logaretm
logaretm merged commit 4b92c64 into developNov 24, 2025
66 checks passed
@logaretm
logaretm deleted the awad/js-549-adblock-plus-blocking-requests-to-sentry-and-monitoring branch November 24, 2025 15:41
Sign up for freeto 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.

3 participants

@logaretm@chargome@github-advanced-security