Open etnichols opened 1 month ago
@etnichols can you share more about the request? Can you verify that the request is indeed made as a fetch
request and not XHR
? What does the code making the request look like? Thanks!
Thanks for the reply @lforst!
Can you verify that the request is indeed made as a fetch request and not XHR?
Confirmed, here is an example snippet of our fetch code used:
/* User Routes */
const fetchCurrentUser = (options) => fetch(`${BASE_URL}/api/user`, {
credentials: 'include',
cache: 'no-store',
})
.then((response) => (response.status === 401 ? (window.location.href = '/login') : response))
.then((response) => response.json());
I can provide a HAR file too if that would be helpful.
.HAR file from our dev environment is here: app.tryinteract.dev-sentry-baggage-issue.har.zip
I wonder if there is some other library involved that patches fetch
, for example to somehow retain request headers across fetch requests. To me, this looks like for some reason (parts of) the request are re-used which, as you pointed out in our source code, we don't account for at the moment.
I also don't really see how this can happen with the code @etnichols shared without a third party interfering. @etnichols would you mind providing a minimal reproduction? Thanks.
While creating the min repro (https://github.com/etnichols/sentry-baggage-min-repro) we found the root cause: re-using a const object for the fetch options
.
❌ passes same object reference to every instantiation of fetchCurrentUser, which causes Sentry code to continually append Baggage
headers on each call:
const FETCH_OPTIONS = {
credentials: 'include',
method: 'GET',
};
const fetchCurrentUser = (options) =>
fetch(`/api/user`, FETCH_OPTIONS).then((response) => response.json());
✅ spread operator creates a new object for each instantiation, no duplicated Baggage headers.
const FETCH_OPTIONS = {
credentials: 'include',
method: 'GET',
};
const fetchCurrentUser = (options) =>
fetch(`/api/user`, { ...FETCH_OPTIONS }).then((response) => response.json());
While you could still consider adding de-dupe logic to the Header ctor code, this is 100% user error 🐒 apologies for the confusion.
I honestly don't consider this a user error! We should make it harder to run into this probably by cloning the object or smth.
Is there an existing issue for this?
How do you use Sentry?
Sentry Saas (sentry.io)
Which SDK are you using?
@sentry/nextjs
SDK Version
7.112.2
Framework Version
13.5.6
Link to Sentry event
n/a
SDK Setup
Steps to Reproduce
Expected Result
Non-duplicated Sentry
Baggage
header.Actual Result
App is experiencing the exact same issue as described in https://github.com/getsentry/sentry-javascript/issues/11500. Each subsequent request made from our NextJS client includes a duplicated entry under the
Baggage
header. For example, we have an/account/settings
page that fires off 3 requests during load:request 1
request 2
request 3
this pattern continues until the one of the fetch calls recieves back a 431 "Request header fields too large" response, which usually results in app hanging until hard refresh.
Using
"@sentry/nextjs": "^7.112.2"
for our Next app.Taking a look at the logic that @lforst mentioned in https://github.com/getsentry/sentry-javascript/issues/11500#issuecomment-2047136837, I suspect this is a bug with the construction of the sentry baggage headers, specifically either here or here.
In both cases, doing a deduplication of existing key-value pairs might resolve the issue: