Environment
@sentry/react: confirmed on both 10.62.0 and 10.74.0 (same behavior on both)
- React 19.2.6, react-router-dom v6 (
reactRouterV6BrowserTracingIntegration)
- Chrome (latest stable), Vite 7 dev server
What we're seeing
A fetch() call made shortly after a hard, full-page navigation (not an SPA route transition — a fresh document load from an external redirect) never settles: neither resolves nor rejects, confirmed for 100+ seconds. The identical request via a genuinely native, unpatched fetch (borrowed from a separate iframe) completes normally in 2-3 seconds.
What we ruled out (all tested live, not assumed)
- SDK version: reproduces identically on
10.62.0 and 10.74.0.
browserTracingIntegration config: setting instrumentPageLoad: false does not stop window.fetch from being wrapped, and the hang still occurs.
- Removing the integration entirely: passing
integrations: [] to Sentry.init() — window.fetch is still wrapped (Sentry's default integrations, e.g. breadcrumbs, aren't disabled by an empty array).
defaultIntegrations: false: window.fetch is still wrapped.
- Never calling
Sentry.init() at all: window.fetch is still wrapped, and the hang still occurs.
- Removing
withSentryReactRouterV6Routing wrapping the router's <Routes>: no change.
The actual finding
window.fetch gets monkey-patched (confirmed via window.fetch.toString() not being [native code], and its source containing sentry/trace/breadcrumb) as soon as anything is imported from @sentry/react anywhere in the module graph — independent of calling Sentry.init(), independent of which integrations are configured, independent of SDK version. We could not find a way to prevent this via public configuration.
Caveat — not yet a minimal, isolated repro
We have a reliable trigger (a real OIDC SSO handoff: external IdP → our backend → redirect back to our SPA on a hard navigation, then an outgoing fetch from the landing component), but we have not isolated the precise minimal condition. Notably, a synthetic test (hard-navigate to the same route with a dummy token, then immediately fetch() a different endpoint) did not reproduce the hang — it succeeded in ~500ms. So "hard navigation + first fetch" alone is not sufficient; something about the specific sequence of app-side work happening between page load and the fetch call (clearing/resetting stored session state, several synchronous state emissions, etc., all before the fetch) appears to be a contributing factor we haven't isolated yet.
Ask
Is eager window.fetch monkey-patching on package import (rather than gated behind Sentry.init()/an active client) expected behavior? Is there a supported way to prevent it? And does the pageload idle-span lifecycle interact with the fetch instrumentation in a way that could produce this kind of hang under a specific sequence of synchronous work happening in the same tick as the outgoing request?
Happy to provide more detail or attempt to build a minimal standalone reproduction if that would help — wanted to report the mechanism evidence first since it took a while to characterize.
Environment
@sentry/react: confirmed on both10.62.0and10.74.0(same behavior on both)reactRouterV6BrowserTracingIntegration)What we're seeing
A
fetch()call made shortly after a hard, full-page navigation (not an SPA route transition — a fresh document load from an external redirect) never settles: neither resolves nor rejects, confirmed for 100+ seconds. The identical request via a genuinely native, unpatchedfetch(borrowed from a separate iframe) completes normally in 2-3 seconds.What we ruled out (all tested live, not assumed)
10.62.0and10.74.0.browserTracingIntegrationconfig: settinginstrumentPageLoad: falsedoes not stopwindow.fetchfrom being wrapped, and the hang still occurs.integrations: []toSentry.init()—window.fetchis still wrapped (Sentry's default integrations, e.g. breadcrumbs, aren't disabled by an empty array).defaultIntegrations: false:window.fetchis still wrapped.Sentry.init()at all:window.fetchis still wrapped, and the hang still occurs.withSentryReactRouterV6Routingwrapping the router's<Routes>: no change.The actual finding
window.fetchgets monkey-patched (confirmed viawindow.fetch.toString()not being[native code], and its source containingsentry/trace/breadcrumb) as soon as anything is imported from@sentry/reactanywhere in the module graph — independent of callingSentry.init(), independent of which integrations are configured, independent of SDK version. We could not find a way to prevent this via public configuration.Caveat — not yet a minimal, isolated repro
We have a reliable trigger (a real OIDC SSO handoff: external IdP → our backend → redirect back to our SPA on a hard navigation, then an outgoing
fetchfrom the landing component), but we have not isolated the precise minimal condition. Notably, a synthetic test (hard-navigate to the same route with a dummy token, then immediatelyfetch()a different endpoint) did not reproduce the hang — it succeeded in ~500ms. So "hard navigation + first fetch" alone is not sufficient; something about the specific sequence of app-side work happening between page load and the fetch call (clearing/resetting stored session state, several synchronous state emissions, etc., all before the fetch) appears to be a contributing factor we haven't isolated yet.Ask
Is eager
window.fetchmonkey-patching on package import (rather than gated behindSentry.init()/an active client) expected behavior? Is there a supported way to prevent it? And does the pageload idle-span lifecycle interact with the fetch instrumentation in a way that could produce this kind of hang under a specific sequence of synchronous work happening in the same tick as the outgoing request?Happy to provide more detail or attempt to build a minimal standalone reproduction if that would help — wanted to report the mechanism evidence first since it took a while to characterize.